rvv040 - Add encodeSaplingAddress function

Added new tests for encodeSaplingAddress and decodeSaplingAddress
This commit is contained in:
Rene V. Vergara A. 2024-04-16 18:51:14 -04:00
parent 058bbfe3f2
commit 06aff8c787
4 changed files with 66 additions and 32 deletions

View file

@ -5,6 +5,16 @@ 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.5.5.2]
### Added
- Added unction to encode a Sappling Address in Human Readable Format Using a SaplingReceiver
`encodeSaplingAddress` a zcash sapling address is returned or Nothing if the function fails
- Added decoding and encoding test
## [0.5.5.1] ## [0.5.5.1]
### Added ### Added

View file

@ -34,32 +34,35 @@ import C.Zcash
) )
import Data.Aeson import Data.Aeson
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as C
import qualified Data.Text as T
import Data.HexString (HexString(..), fromText, hexString, toBytes, toText) import Data.HexString (HexString(..), fromText, hexString, toBytes, toText)
import Data.Word import Data.Word
import Foreign.Rust.Marshall.Variable import Foreign.Rust.Marshall.Variable
( withPureBorshVarBuffer ( withPureBorshVarBuffer
, withPureBorshVarBuffer , withPureBorshVarBuffer
) )
import ZcashHaskell.Types import ZcashHaskell.Types
( AccountId --import ZcashHaskell.Types
, CoinType -- ( AccountId
, DecodedNote(..) -- , CoinType
, RawData(..) -- , DecodedNote(..)
, RawTxResponse(..) -- , RawData(..)
, SaplingAddress(..) -- , RawTxResponse(..)
, SaplingCommitmentTree(..) -- , SaplingAddress(..)
, SaplingReceiver(..) -- , SaplingCommitmentTree(..)
, SaplingSpendingKey(..) -- , SaplingReceiver(..)
, SaplingWitness(..) -- , SaplingSpendingKey(..)
, Scope(..) -- , SaplingWitness(..)
, Seed(..) -- , Scope(..)
, ShieldedOutput(..) -- , Seed(..)
, ToBytes(..) -- , ShieldedOutput(..)
, ZcashNet(..) -- , ToBytes(..)
, decodeHexText -- , ZcashNet(..)
, getValue -- , decodeHexText
) -- , getValue
import ZcashHaskell.Utils (decodeBech32) -- )
import ZcashHaskell.Utils (decodeBech32, encodeBech32, encodeBech32m)
-- | Check if given bytesting is a valid encoded shielded address -- | Check if given bytesting is a valid encoded shielded address
isValidShieldedAddress :: BS.ByteString -> Bool isValidShieldedAddress :: BS.ByteString -> Bool
@ -208,25 +211,32 @@ getSaplingNotePosition :: SaplingWitness -> Integer
getSaplingNotePosition = getSaplingNotePosition =
fromIntegral . rustWrapperReadSaplingPosition . hexBytes . sapWit fromIntegral . rustWrapperReadSaplingPosition . hexBytes . sapWit
-- | Encode a SaplingReceiver into HRF text
encodeSaplingAddress :: ZcashNet -> SaplingReceiver -> Maybe T.Text
encodeSaplingAddress net sr = do
case net of
MainNet ->
Just $ encodeBech32 (C.pack sapPaymentAddressHrp) (getBytes sr)
TestNet ->
Just $ encodeBech32 (C.pack sapTestPaymentAddressHrp) (getBytes sr)
-- | Helper to get de Nework Id from FFI response
getNetId:: [Word8] -> ZcashNet getNetId:: [Word8] -> ZcashNet
getNetId [x] = do getNetId [x] = do
case x of case x of
1 -> MainNet 1 -> MainNet
2 -> TestNet 2 -> TestNet
-- | decode a Sapling address -- | decode a Sapling address
decodeSaplingAddress :: BS.ByteString -> Maybe SaplingAddress decodeSaplingAddress :: BS.ByteString -> Maybe SaplingAddress
decodeSaplingAddress sapling_address = do decodeSaplingAddress sapling_address = do
if BS.length sa > 1 if BS.length sa > 1
then do then do
let sa0 = BS.unpack sa let sa0 = BS.unpack sa
Just $ SaplingAddress (getNetId (take 1 sa0)) (BS.pack (drop 1 sa0)) Just $ SaplingAddress (getNetId (take 1 sa0))
$ SaplingReceiver (BS.pack (drop 1 sa0))
else Nothing else Nothing
where where
sa = sa =
withPureBorshVarBuffer $ withPureBorshVarBuffer $
rustWrapperDecodeSaplingAddress sapling_address rustWrapperDecodeSaplingAddress sapling_address

View file

@ -480,9 +480,9 @@ instance ToBytes SaplingReceiver where
data SaplingAddress = SaplingAddress data SaplingAddress = SaplingAddress
{ {
net_type :: !ZcashNet net_type :: !ZcashNet
, address :: !BS.ByteString , sa_receiver :: !SaplingReceiver
} deriving (Eq, Prelude.Show, Read) } deriving (Eq, Prelude.Show, Read)
-- | Type to represent a Sapling Shielded Spend as provided by the @getrawtransaction@ RPC method -- | Type to represent a Sapling Shielded Spend as provided by the @getrawtransaction@ RPC method
data ShieldedSpend = ShieldedSpend data ShieldedSpend = ShieldedSpend
{ sp_cv :: !HexString { sp_cv :: !HexString

View file

@ -58,6 +58,7 @@ import ZcashHaskell.Sapling
, matchSaplingAddress , matchSaplingAddress
, updateSaplingCommitmentTree , updateSaplingCommitmentTree
, decodeSaplingAddress , decodeSaplingAddress
, encodeSaplingAddress
) )
import ZcashHaskell.Transparent import ZcashHaskell.Transparent
import ZcashHaskell.Types import ZcashHaskell.Types
@ -916,14 +917,27 @@ main = do
describe "Decode a Sapling Address (MainNet)" $ do describe "Decode a Sapling Address (MainNet)" $ do
let sa = decodeSaplingAddress "zs1waxrpde36rlrjdwfhnvw030sn29lzwmvmeupd8x2uuqgypaafx7mqcy0ep8yf2xtg30n5424t60" let sa = decodeSaplingAddress "zs1waxrpde36rlrjdwfhnvw030sn29lzwmvmeupd8x2uuqgypaafx7mqcy0ep8yf2xtg30n5424t60"
it "Try to decode a valid MainNet Sapling Address" $ do it "Try to decode a valid MainNet Sapling Address" $ do
print sa case sa of
sa `shouldNotBe` Nothing Nothing -> assertFailure "Failed to decode MainNet SaplingAddress"
Just s -> do -- Sapling address decoded succesfully
let sh = encodeSaplingAddress (net_type s) (sa_receiver s)
case sh of
Nothing -> assertFailure "Failed to encode MainNet SaplingAddress"
Just zsh -> do
print zsh
zsh `shouldBe` "zs1waxrpde36rlrjdwfhnvw030sn29lzwmvmeupd8x2uuqgypaafx7mqcy0ep8yf2xtg30n5424t60"
describe "Decode a Sapling Address (TestNet)" $ do describe "Decode a Sapling Address (TestNet)" $ do
let sa = decodeSaplingAddress "ztestsapling188csdsvhdny25am8ume03qr2026hdy03zpg5pq7jmmfxtxtct0e93p0rg80yfxvynqd4gwlwft5" let sa = decodeSaplingAddress "ztestsapling188csdsvhdny25am8ume03qr2026hdy03zpg5pq7jmmfxtxtct0e93p0rg80yfxvynqd4gwlwft5"
it "Try to decode a valid TestNet Sapling Address " $ do it "Try to decode a valid TestNet Sapling Address " $ do
print sa case sa of
sa `shouldNotBe` Nothing Nothing -> assertFailure "Failed to decode TestNet SaplingAddress"
Just s -> do -- Sapling address decoded succesfully
let sh = encodeSaplingAddress (net_type s) (sa_receiver s)
case sh of
Nothing -> assertFailure "Failed to encode TestNet SaplingAddress"
Just zsh -> do
print zsh
zsh `shouldBe` "ztestsapling188csdsvhdny25am8ume03qr2026hdy03zpg5pq7jmmfxtxtct0e93p0rg80yfxvynqd4gwlwft5"
-- | Properties -- | Properties
prop_PhraseLength :: Property prop_PhraseLength :: Property