Enhances memo decoding
This commit is contained in:
parent
9cc1950d94
commit
462c72c882
7 changed files with 35 additions and 14 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.3.0.0]
|
||||
|
||||
### Changed
|
||||
|
||||
- Changed decoding of memos to support Unicode (emojis!)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Displaying transactions for view-only addresses
|
||||
|
||||
## [0.2.0.0]
|
||||
|
||||
### Added
|
||||
|
|
|
@ -58,6 +58,9 @@ Zenith will attempt to connect to the node and check compatibility. Connections
|
|||
- `send`: Prompts the user to prepare an outgoing transaction, selecting the source address, validating the destination address, the amount and the memo.
|
||||
- If the source is a transparent address, the privacy policy is set to `AllowRevealedSenders`, favoring the shielding of funds when sent to a UA.
|
||||
- If the source is a shielded address, the privacy policy is set to `AllowRevealedAmounts`, favoring the move of funds from legacy shielded pools to Orchard.
|
||||
- `uri`: Prompts the user to select the source account and to enter a [ZIP-321](https://zips.z.cash/zip-0321) compliant URI to generate and send a transaction.
|
||||
- `exit`: Ends the session.
|
||||
|
||||
### Support
|
||||
|
||||
If you would like to support the development of Zenith, please visit our [Free2Z](https://free2z.com/zenith-full-node-cli) page.
|
||||
|
|
|
@ -9,6 +9,7 @@ import Data.Configurator
|
|||
import Data.Default (def)
|
||||
import Data.Sort
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.IO as TIO
|
||||
import Data.Time.Clock.POSIX
|
||||
import System.Console.StructuredCLI
|
||||
import System.Exit
|
||||
|
@ -155,7 +156,7 @@ displayTx t = do
|
|||
putStr "Zats: "
|
||||
print $ zamountZat t
|
||||
putStr "Memo: "
|
||||
putStrLn $ T.unpack $ zmemo t
|
||||
TIO.putStrLn $ zmemo t
|
||||
putStrLn "-----"
|
||||
|
||||
processUri :: B.ByteString -> B.ByteString -> Commands ()
|
||||
|
|
|
@ -50,6 +50,7 @@ executables:
|
|||
- -rtsopts
|
||||
- -with-rtsopts=-N
|
||||
- -Wall
|
||||
- -Wunused-imports
|
||||
dependencies:
|
||||
- zenith
|
||||
- configurator
|
||||
|
|
|
@ -19,7 +19,10 @@ import Data.Functor (void)
|
|||
import Data.Maybe
|
||||
import qualified Data.Scientific as Scientific
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as E
|
||||
import Data.Text.Encoding.Error (lenientDecode)
|
||||
import qualified Data.Vector as V
|
||||
import Data.Word
|
||||
import GHC.Generics
|
||||
import Haskoin.Address.Bech32
|
||||
import Network.HTTP.Simple
|
||||
|
@ -199,7 +202,7 @@ instance FromJSON ZcashTx where
|
|||
aZ <- obj .: "amountZat"
|
||||
bh <- obj .: "blockheight"
|
||||
bt <- obj .: "blocktime"
|
||||
c <- obj .: "change"
|
||||
c <- obj .:? "change"
|
||||
conf <- obj .: "confirmations"
|
||||
m <- obj .:? "memo"
|
||||
pure $
|
||||
|
@ -209,11 +212,11 @@ instance FromJSON ZcashTx where
|
|||
aZ
|
||||
bh
|
||||
bt
|
||||
c
|
||||
(fromMaybe False c)
|
||||
conf
|
||||
(case m of
|
||||
Nothing -> ""
|
||||
Just m' -> T.pack (filter (/= '\NUL') $ decodeHexText m'))
|
||||
Just m' -> T.filter (/= '\NUL') $ decodeHexText m')
|
||||
|
||||
instance ToJSON ZcashTx where
|
||||
toJSON (ZcashTx t a aZ bh bt c conf m) =
|
||||
|
@ -288,12 +291,15 @@ instance FromJSON OpResult where
|
|||
pure $ OpResult s m t
|
||||
|
||||
-- | Helper function to turn a hex-encoded memo strings to readable text
|
||||
decodeHexText :: String -> String
|
||||
decodeHexText hexText
|
||||
| null chunk = ""
|
||||
| otherwise = chr (read ("0x" <> chunk)) : decodeHexText (drop 2 hexText)
|
||||
decodeHexText :: String -> T.Text
|
||||
decodeHexText h = E.decodeUtf8With lenientDecode $ B.pack $ hexRead h
|
||||
where
|
||||
chunk = take 2 hexText
|
||||
hexRead hexText
|
||||
| null chunk = []
|
||||
| otherwise =
|
||||
fromIntegral (read ("0x" <> chunk)) : hexRead (drop 2 hexText)
|
||||
where
|
||||
chunk = take 2 hexText
|
||||
|
||||
-- | Helper function to turn a string into a hex-encoded string
|
||||
encodeHexText :: String -> String
|
||||
|
@ -375,7 +381,7 @@ listTxs user pwd zaddy = do
|
|||
makeZcashCall user pwd "z_listreceivedbyaddress" [String $ addy zaddy]
|
||||
let rpcResp = decode response :: Maybe (RpcResponse [ZcashTx])
|
||||
case rpcResp of
|
||||
Nothing -> fail "Couldn't parse node response"
|
||||
Nothing -> fail "listTxs: Couldn't parse node response"
|
||||
Just res -> do
|
||||
return $ result res
|
||||
|
||||
|
@ -578,13 +584,13 @@ sendWithUri user pwd fromAddy uri = do
|
|||
Just amt -> do
|
||||
putStrLn $ " Valid ZEC amount: " ++ show amt
|
||||
let decodedMemo = B64.decodeLenient $ C.pack parsedEncodedMemo
|
||||
putStrLn $ " Memo: " ++ show decodedMemo
|
||||
putStrLn $ " Memo: " ++ C.unpack decodedMemo
|
||||
sendTx
|
||||
user
|
||||
pwd
|
||||
fromAddy
|
||||
(T.pack parsedAddress)
|
||||
amt
|
||||
(show decodedMemo)
|
||||
(C.unpack decodedMemo)
|
||||
else putStrLn " Invalid address"
|
||||
else putStrLn "URI is not compliant with ZIP-321"
|
||||
|
|
|
@ -42,7 +42,7 @@ packages:
|
|||
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
|
||||
#
|
||||
# extra-deps: []
|
||||
|
||||
#
|
||||
# Override default flag values for local packages and extra-deps
|
||||
# flags: {}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ executable zenith
|
|||
Paths_zenith
|
||||
hs-source-dirs:
|
||||
app
|
||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
|
||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -Wunused-imports
|
||||
build-depends:
|
||||
base >=4.7 && <5
|
||||
, bytestring
|
||||
|
|
Loading…
Reference in a new issue