Compare commits

..

No commits in common. "1e795dbcea5ea0095341a2c7d3bf5934898488d5" and "477817f37f414a459d70b1f89e950f85438ca267" have entirely different histories.

10 changed files with 252 additions and 322 deletions

View file

@ -19,7 +19,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Constants for Zcash protocol - Constants for Zcash protocol
- Types for Spending Keys and Receivers for Sapling and Orchard - Types for Spending Keys and Receivers for Sapling and Orchard
- Function to generate an Orchard receiver - Function to generate an Orchard receiver
- Function to generate a Sapling receiver
### Changed ### Changed

View file

@ -1314,6 +1314,7 @@ dependencies = [
"borsh 0.10.3", "borsh 0.10.3",
"f4jumble", "f4jumble",
"haskell-ffi", "haskell-ffi",
"nom",
"orchard 0.7.1", "orchard 0.7.1",
"proc-macro2", "proc-macro2",
"zcash_address 0.2.0", "zcash_address 0.2.0",

View file

@ -17,6 +17,7 @@ zcash_primitives = "0.13.0"
zcash_client_backend = "0.10.0" zcash_client_backend = "0.10.0"
zip32 = "0.1.0" zip32 = "0.1.0"
proc-macro2 = "1.0.66" proc-macro2 = "1.0.66"
nom = "7.1.3"
[features] [features]
capi = [] capi = []

View file

@ -24,23 +24,15 @@ use haskell_ffi::{
use zip32; use zip32;
use zcash_primitives::{ use zcash_primitives::{
zip32::{ zip32::Scope as SaplingScope,
Scope as SaplingScope,
sapling_find_address,
sapling::DiversifierKey
},
zip339::{Count, Mnemonic}, zip339::{Count, Mnemonic},
transaction::components::sapling::{ transaction::components::sapling::{
GrothProofBytes, GrothProofBytes,
OutputDescription OutputDescription,
}, },
sapling::{ sapling::{
PaymentAddress, PaymentAddress,
keys::{ keys::PreparedIncomingViewingKey as SaplingPreparedIncomingViewingKey,
PreparedIncomingViewingKey as SaplingPreparedIncomingViewingKey,
ExpandedSpendingKey,
FullViewingKey as SaplingFullViewingKey
},
note_encryption::SaplingDomain note_encryption::SaplingDomain
}, },
transaction::Transaction, transaction::Transaction,
@ -57,12 +49,13 @@ use zcash_address::{
ZcashAddress ZcashAddress
}; };
use zcash_client_backend::keys::sapling::{ use zcash_client_backend::keys::{
ExtendedFullViewingKey, sapling,
ExtendedSpendingKey sapling::ExtendedFullViewingKey,
}; sapling::ExtendedSpendingKey};
use zcash_primitives::zip32::{ AccountId, DiversifierIndex }; use zcash_primitives::zip32::{ AccountId, DiversifierIndex };
use std::slice;
use orchard::{ use orchard::{
Action, Action,
@ -631,6 +624,7 @@ pub extern "C" fn rust_wrapper_sapling_spendingkey(
out: *mut u8, out: *mut u8,
out_len: &mut usize out_len: &mut usize
){ ){
println!("Starting extended spending key generation....");
let seed: Vec<u8> = marshall_from_haskell_var(iseed, iseed_len, RW); let seed: Vec<u8> = marshall_from_haskell_var(iseed, iseed_len, RW);
if ( seed.len() != 64 ) { if ( seed.len() != 64 ) {
// invalid seed length // invalid seed length
@ -640,7 +634,8 @@ pub extern "C" fn rust_wrapper_sapling_spendingkey(
// Returns a byte array (169 bytes) // Returns a byte array (169 bytes)
let su8 = &seed; let su8 = &seed;
let seedu8 : &[u8] = &su8; let seedu8 : &[u8] = &su8;
let extsk: ExtendedSpendingKey = ExtendedSpendingKey::master(&seedu8); println!("Seed : {:?}\n", &seedu8);
let extsk: ExtendedSpendingKey = sapling::ExtendedSpendingKey::master(&seedu8);
let extsk_bytes = extsk.to_bytes().to_vec(); let extsk_bytes = extsk.to_bytes().to_vec();
marshall_to_haskell_var(&extsk_bytes, out, out_len, RW); marshall_to_haskell_var(&extsk_bytes, out, out_len, RW);
} }
@ -650,25 +645,94 @@ pub extern "C" fn rust_wrapper_sapling_spendingkey(
pub extern "C" fn rust_wrapper_sapling_paymentaddress( pub extern "C" fn rust_wrapper_sapling_paymentaddress(
extspk: *const u8, extspk: *const u8,
extspk_len: usize, extspk_len: usize,
div_ix: u32, // divIx: u32,
out: *mut u8, out: *mut u8,
out_len: &mut usize out_len: &mut usize
){ ){
let extspk: Vec<u8> = marshall_from_haskell_var(extspk, extspk_len, RW); // println!("Starting paymentAddress generation....");
let expsk = ExpandedSpendingKey::from_spending_key(&extspk); let extspkb: Vec<u8> = marshall_from_haskell_var(extspk, extspk_len, RW);
let fvk = SaplingFullViewingKey::from_expanded_spending_key(&expsk); if ( extspkb.len() != 169 ) {
let dk = DiversifierKey::master(&extspk); // invalid ExtendedSpenndingKey Array length
let result = sapling_find_address(&fvk, &dk, DiversifierIndex::from(div_ix)); println!("Invalid ExtendedSpendingKey....");
match result {
Some((_d, p_address)) => {
marshall_to_haskell_var(&p_address.to_bytes().to_vec(), out, out_len, RW);
},
None => {
marshall_to_haskell_var(&vec![0], out, out_len, RW); marshall_to_haskell_var(&vec![0], out, out_len, RW);
} else {
// Process
// println!("Extended Spending Key validated, continue ....");
let extspkbu8 = &extspkb;
let xsku8 : &[u8] = &extspkbu8;
let xsk = match sapling::ExtendedSpendingKey::from_bytes(&xsku8) {
Ok ( x ) => x,
Err ( err ) => {
// Error recovering ExtendedSpendingKey from bytes
marshall_to_haskell_var(&vec![0], out, out_len, RW);
return
} }
};
// Obtain the DiversifiableFullViewingKey from ExtendedSpendingKey
let dfvk = xsk.to_diversifiable_full_viewing_key();
// Obtain the Address from the DiversifiableFullViewingKey
// println!("dfvk -> \n{:?}", dfvk);
// let divIndex : DiversifierIndex = divIx.into();
// println!("divIndex -> {:?}", divIndex);
let (divIx, paddress) = dfvk.default_address();
// println!("Rust pmtAddress - \n{:?}\n\nRust Diversifier - \n{:?}\n", paddress, divIx);
let pmtAddress = paddress.to_bytes();
// println!("\nRust pntAddress as byte array -\n{:?}\n", pmtAddress);
marshall_to_haskell_var(&pmtAddress.to_vec(), out, out_len, RW);
} }
} }
#[no_mangle]
pub extern "C" fn rust_wrapper_sapling_find_paymentaddress(
extspk: *const u8,
extspk_len: usize,
divIx: u32,
out: *mut u8,
out_len: &mut usize
){
println!("Starting paymentAddress generation using Find_Address()....");
let extspkb: Vec<u8> = marshall_from_haskell_var(extspk, extspk_len, RW);
if ( extspkb.len() != 169 ) {
// invalid ExtendedSpenndingKey Array length
println!("Invalid ExtendedSpendingKey....");
marshall_to_haskell_var(&vec![0], out, out_len, RW);
} else {
// Process
println!("Extended Spending Key validated, continue ....");
let extspkbu8 = &extspkb;
let xsku8 : &[u8] = &extspkbu8;
let xsk = match sapling::ExtendedSpendingKey::from_bytes(&xsku8) {
Ok ( x ) => x,
Err ( err ) => {
// Error recovering ExtendedSpendingKey from bytes
marshall_to_haskell_var(&vec![0], out, out_len, RW);
return
}
};
println!("Obtain a DiversifierIndex from u32 parameter {:?}....",divIx);
let diversifierIndex : DiversifierIndex = divIx.into();
// Obtain the DiversifiableFullViewingKey from ExtendedSpendingKey
let dfvk = xsk.to_diversifiable_full_viewing_key();
// Obtain the Address from the DiversifiableFullViewingKey
// println!("dfvk -> \n{:?}", dfvk);
// let divIndex : DiversifierIndex = divIx.into();
// println!("divIndex -> {:?}", divIndex);
let result = dfvk.find_address(diversifierIndex)
.map (|(divIx,paddress) | {
println!("Rust pmtAddress - \n{:?}\n\nRust Diversifier - \n{:?}\n", paddress, divIx);
let pmtAddress = paddress.to_bytes();
println!("\nRust pntAddress as byte array -\n{:?}\n", pmtAddress);
marshall_to_haskell_var(&pmtAddress.to_vec(), out, out_len, RW);
//
})
.unwrap_or_else(|| {
// Handle the case where the function returns None
println!("Rust - Error finding payment address.... ");
marshall_to_haskell_var(&vec![0], out, out_len, RW);
return
});
}
}
#[no_mangle] #[no_mangle]
pub extern "C" fn rust_wrapper_derive_orchard_spending_key( pub extern "C" fn rust_wrapper_derive_orchard_spending_key(
seed: *const u8, seed: *const u8,

View file

@ -141,7 +141,14 @@ import ZcashHaskell.Types
-> `()' -> `()'
#} #}
{# fun unsafe rust_wrapper_sapling_paymentaddress as rustWrapperSaplingPaymentAddress {# fun unsafe rust_wrapper_sapling_paymentaddress as rustWrapperPaymentAddress
{ toBorshVar* `BS.ByteString'&
, getVarBuffer `Buffer (BS.ByteString)'&
}
-> `()'
#}
{# fun unsafe rust_wrapper_sapling_find_paymentaddress as rustWrapperFindPaymentAddress
{ toBorshVar* `BS.ByteString'& { toBorshVar* `BS.ByteString'&
, `Word32' , `Word32'
, getVarBuffer `Buffer (BS.ByteString)'& , getVarBuffer `Buffer (BS.ByteString)'&

View file

@ -21,13 +21,15 @@ import C.Zcash
( rustWrapperIsShielded ( rustWrapperIsShielded
, rustWrapperSaplingCheck , rustWrapperSaplingCheck
, rustWrapperSaplingNoteDecode , rustWrapperSaplingNoteDecode
, rustWrapperSaplingPaymentAddress
, rustWrapperSaplingSpendingkey , rustWrapperSaplingSpendingkey
, rustWrapperPaymentAddress
, rustWrapperFindPaymentAddress
, rustWrapperSaplingVkDecode , rustWrapperSaplingVkDecode
, rustWrapperTxParse , rustWrapperTxParse
) )
import Data.Aeson import Data.Aeson
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
import Data.ByteString.Lazy as BL
import Data.HexString (HexString(..), toBytes) import Data.HexString (HexString(..), toBytes)
import Data.Word import Data.Word
import Foreign.Rust.Marshall.Variable import Foreign.Rust.Marshall.Variable
@ -35,18 +37,16 @@ import Foreign.Rust.Marshall.Variable
, withPureBorshVarBuffer , withPureBorshVarBuffer
) )
import ZcashHaskell.Types import ZcashHaskell.Types
( AccountId ( DecodedNote(..)
, CoinType
, DecodedNote(..)
, RawData(..) , RawData(..)
, RawTxResponse(..) , RawTxResponse(..)
, SaplingReceiver , SaplingSKeyParams(..)
, SaplingSpendingKey(..)
, Seed(..)
, ShieldedOutput(..) , ShieldedOutput(..)
, decodeHexText , decodeHexText
, AccountId
, CoinType
) )
import ZcashHaskell.Utils (decodeBech32) import ZcashHaskell.Utils
-- | 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
@ -92,25 +92,22 @@ instance FromJSON RawTxResponse where
Just o' -> do Just o' -> do
a <- o' .: "actions" a <- o' .: "actions"
pure $ RawTxResponse i h (getShieldedOutputs h) a ht c b pure $ RawTxResponse i h (getShieldedOutputs h) a ht c b
-- --
-- | Attempts to obtain a sapling SpendingKey using a HDSeed -- | Attempts to obtain a sapling SpendinKey using a HDSeed, a Coin Type and an Account ID
genSaplingSpendingKey :: Seed -> Maybe SaplingSpendingKey genSaplingSpendingKey :: BS.ByteString -> BS.ByteString
genSaplingSpendingKey seed = do genSaplingSpendingKey seed = do
if BS.length res == 196 let res = withPureBorshVarBuffer (rustWrapperSaplingSpendingkey seed )
then Just res res
else Nothing --
where -- | Attempts to generate a sapling Payment Address using an ExtendedSpendingKey
res = withPureBorshVarBuffer (rustWrapperSaplingSpendingkey seed) genSaplingPaymentAddress :: BS.ByteString -> BS.ByteString
genSaplingPaymentAddress extspk = do
let pmtaddress = withPureBorshVarBuffer (rustWrapperPaymentAddress extspk )
pmtaddress
-- --
-- | Attempts to generate a sapling Payment Address using an ExtendedSpendingKey and a Diversifier Index -- | Attempts to generate a sapling Payment Address using an ExtendedSpendingKey
genSaplingPaymentAddress :: SaplingSpendingKey -> Int -> Maybe SaplingReceiver genSaplingFindPaymentAddress :: BS.ByteString -> Word32 -> BS.ByteString
genSaplingPaymentAddress extspk i = genSaplingFindPaymentAddress extspk divIx = do
if BS.length res == 43 let pmtaddress = withPureBorshVarBuffer (rustWrapperFindPaymentAddress extspk divIx)
then Just res pmtaddress
else Nothing
where
res =
withPureBorshVarBuffer
(rustWrapperSaplingPaymentAddress extspk (fromIntegral i))

View file

@ -346,6 +346,16 @@ data DecodedNote = DecodedNote
deriving anyclass (Data.Structured.Show) deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct DecodedNote deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct DecodedNote
-- } Type to represent parameters to call rust zcash library
data SaplingSKeyParams = SaplingSKeyParams
{ hdseed :: BS.ByteString -- ^ seed required for sappling spending key generation
, coin_type :: Word32 -- ^ coin_type
, account_id :: Word32 -- ^ account id
} deriving stock (Eq, Prelude.Show, GHC.Generic)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct SaplingSKeyParams
-- * Helpers -- * Helpers
-- | Helper function to turn a hex-encoded string to bytestring -- | Helper function to turn a hex-encoded string to bytestring
decodeHexText :: String -> BS.ByteString decodeHexText :: String -> BS.ByteString

View file

@ -37,8 +37,8 @@ import Foreign.Marshal.Array (allocaArray, peekArray)
import Foreign.Ptr (Ptr) import Foreign.Ptr (Ptr)
import Data.Word import Data.Word
-- | -- |
-- | Decode the given bytestring using Bech32 -- | Decode the given bytestring using Bech32
decodeBech32 :: BS.ByteString -> RawData decodeBech32 :: BS.ByteString -> RawData
decodeBech32 = withPureBorshVarBuffer . rustWrapperBech32Decode decodeBech32 = withPureBorshVarBuffer . rustWrapperBech32Decode
@ -88,3 +88,13 @@ makeZebraCall host port m params = do
setRequestHost (E.encodeUtf8 host) $ setRequestHost (E.encodeUtf8 host) $
setRequestMethod "POST" defaultRequest setRequestMethod "POST" defaultRequest
httpJSON myRequest httpJSON myRequest
-- + Misc functions
-- Convert an array of Word8 to a ByteString
word8ArrayToByteString :: [Word8] -> BS.ByteString
word8ArrayToByteString = BS.pack
-- Convert [Word8] to String
word8ToString :: [Word8] -> String
word8ToString = map (toEnum . fromEnum)

View file

@ -41,21 +41,19 @@ import ZcashHaskell.Keys (generateWalletSeedPhrase, getWalletSeed)
import ZcashHaskell.Orchard import ZcashHaskell.Orchard
import ZcashHaskell.Sapling import ZcashHaskell.Sapling
( decodeSaplingOutput ( decodeSaplingOutput
, genSaplingPaymentAddress
, genSaplingSpendingKey
, getShieldedOutputs , getShieldedOutputs
, isValidSaplingViewingKey , isValidSaplingViewingKey
, isValidShieldedAddress , isValidShieldedAddress
, matchSaplingAddress , matchSaplingAddress
, genSaplingSpendingKey
, genSaplingPaymentAddress
, genSaplingFindPaymentAddress
) )
import ZcashHaskell.Transparent import ZcashHaskell.Transparent
--(encodeTransparent) --(encodeTransparent)
import ZcashHaskell.Types import ZcashHaskell.Types
( AccountId ( BlockResponse(..)
, BlockResponse(..)
, CoinType(..) , CoinType(..)
, CoinType
, DecodedNote(..) , DecodedNote(..)
, OrchardAction(..) , OrchardAction(..)
, Phrase(..) , Phrase(..)
@ -65,17 +63,20 @@ import ZcashHaskell.Types
, UnifiedAddress(..) , UnifiedAddress(..)
, UnifiedFullViewingKey(..) , UnifiedFullViewingKey(..)
, decodeHexText , decodeHexText
, AccountId
, CoinType
, getValue , getValue
) )
import ZcashHaskell.Utils import ZcashHaskell.Utils
import Data.Word
import Foreign.C.Types import Foreign.C.Types
import Data.Word
import Haskoin.Crypto.Keys.Extended import Haskoin.Crypto.Keys.Extended
m2bs :: Maybe BS.ByteString -> BS.ByteString m2bs :: Maybe BS.ByteString -> BS.ByteString
m2bs x = fromMaybe "" x m2bs x = fromMaybe "" x
main :: IO () main :: IO ()
main = do main = do
hspec $ do hspec $ do
@ -483,251 +484,102 @@ main = do
msg `shouldBe` "t1LPWuQnjCRH7JAeEErSXKixcUteLJRJjKD" msg `shouldBe` "t1LPWuQnjCRH7JAeEErSXKixcUteLJRJjKD"
describe "Transparent Private and Publicc Key Generation" $ do describe "Transparent Private and Publicc Key Generation" $ do
it "Obtain a transparent extended private key from HDSeed" $ do it "Obtain a transparent extended private key from HDSeed" $ do
let hdseed = let hdseed = [206, 61, 120, 38,
[ 206 206, 40, 201, 62,
, 61 83, 175, 151, 131,
, 120 218, 141, 206, 254,
, 38 28, 244, 172, 213,
, 206 128, 248, 156, 45,
, 40 204, 44, 169, 3,
, 201 162, 188, 16, 173,
, 62 192, 164, 96, 148,
, 83 91, 52, 244, 83,
, 175 149, 169, 82, 196,
, 151 199, 53, 177, 170,
, 131 1, 6, 0, 120,
, 218 170, 2, 238, 219,
, 141 241, 243, 172, 178,
, 206 104, 81, 159, 144
, 254
, 28
, 244
, 172
, 213
, 128
, 248
, 156
, 45
, 204
, 44
, 169
, 3
, 162
, 188
, 16
, 173
, 192
, 164
, 96
, 148
, 91
, 52
, 244
, 83
, 149
, 169
, 82
, 196
, 199
, 53
, 177
, 170
, 1
, 6
, 0
, 120
, 170
, 2
, 238
, 219
, 241
, 243
, 172
, 178
, 104
, 81
, 159
, 144
] :: [Word8] ] :: [Word8]
let xtpvk = genTransparentPrvKey (BS.pack hdseed) let xtpvk = genTransparentPrvKey (word8ArrayToByteString hdseed)
let testpvk = let testpvk = XPrvKey 0 "0000000000" 0 "fb5b9b89d3e9dfdebeaabd15de8fbc7e9a140b7f2de2b4034c2573425d39aceb" "46aa0cd24a6e05709591426a4e682dd5406de4e75a39c0f410ee790403880943"
XPrvKey
0
"0000000000"
0
"fb5b9b89d3e9dfdebeaabd15de8fbc7e9a140b7f2de2b4034c2573425d39aceb"
"46aa0cd24a6e05709591426a4e682dd5406de4e75a39c0f410ee790403880943"
xtpvk `shouldBe` testpvk xtpvk `shouldBe` testpvk
-- describe "Obtain transparent public key from private key" $ do
it "Obtain a transparent extended public key from private key" $ do it "Obtain a transparent extended public key from private key" $ do
let testpvk = let testpvk = XPrvKey 0 "0000000000" 0 "fb5b9b89d3e9dfdebeaabd15de8fbc7e9a140b7f2de2b4034c2573425d39aceb" "46aa0cd24a6e05709591426a4e682dd5406de4e75a39c0f410ee790403880943"
XPrvKey let testpbk = XPubKey 0 "00000000" 0 "fb5b9b89d3e9dfdebeaabd15de8fbc7e9a140b7f2de2b4034c2573425d39aceb" "279bda9c704f6da479cedb12c7cf773b3a348569dc1cfa6002526bad67674fd737b84a2bdb1199ecab1c9fed1b9a38aba5ba19259c1510d733a2376118515cd8"
0
"0000000000"
0
"fb5b9b89d3e9dfdebeaabd15de8fbc7e9a140b7f2de2b4034c2573425d39aceb"
"46aa0cd24a6e05709591426a4e682dd5406de4e75a39c0f410ee790403880943"
let testpbk =
XPubKey
0
"00000000"
0
"fb5b9b89d3e9dfdebeaabd15de8fbc7e9a140b7f2de2b4034c2573425d39aceb"
"279bda9c704f6da479cedb12c7cf773b3a348569dc1cfa6002526bad67674fd737b84a2bdb1199ecab1c9fed1b9a38aba5ba19259c1510d733a2376118515cd8"
let xtpubkIO = genTransparentPubKey testpvk let xtpubkIO = genTransparentPubKey testpvk
xtpubk <- xtpubkIO xtpubk <- xtpubkIO
---print $ show xtpubk ---print $ show xtpubk
xtpubk `shouldBe` testpbk xtpubk `shouldBe` testpbk
describe "Sapling SpendingKey test" $ do describe "Sapling SpendingKey test" $ do
let hdseed = it "Call function with parameters" $ do
BS.pack $ let hdseed = [206, 61, 120, 38,
[ 206 206, 40, 201, 62,
, 61 83, 175, 151, 131,
, 120 218, 141, 206, 254,
, 38 28, 244, 172, 213,
, 206 128, 248, 156, 45,
, 40 204, 44, 169, 3,
, 201 162, 188, 16, 173,
, 62 192, 164, 96, 148,
, 83 91, 52, 244, 83,
, 175 149, 169, 82, 196,
, 151 199, 53, 177, 170,
, 131 1, 6, 0, 120,
, 218 170, 2, 238, 219,
, 141 241, 243, 172, 178,
, 206 104, 81, 159, 144
, 254 ] :: [Word8]
, 28 let msg = genSaplingSpendingKey (word8ArrayToByteString hdseed)
, 244 let msgArr = BS.unpack msg
, 172 length msgArr `shouldBe` 169
, 213
, 128
, 248
, 156
, 45
, 204
, 44
, 169
, 3
, 162
, 188
, 16
, 173
, 192
, 164
, 96
, 148
, 91
, 52
, 244
, 83
, 149
, 169
, 82
, 196
, 199
, 53
, 177
, 170
, 1
, 6
, 0
, 120
, 170
, 2
, 238
, 219
, 241
, 243
, 172
, 178
, 104
, 81
, 159
, 144
]
--xit "Call function with parameters" $ do
--let msg = genSaplingSpendingKey (word8ArrayToByteString hdseed)
--let msgArr = BS.unpack msg
--if (length msgArr) == 169
--then True
--else False
it "Generate Sapling spending key" $ do
p <- generateWalletSeedPhrase
let s = getWalletSeed p
genSaplingSpendingKey <$> s `shouldNotBe` Nothing
describe "Sapling Payment Address generation test" $ do describe "Sapling Payment Address generation test" $ do
it "Call genSaplingPaymentAddress" $ do it "Call genSaplingPaymentAddress" $ do
let hdseed1 = let hdseed1 = [206, 61, 120, 38,
[ 206 206, 40, 201, 62,
, 61 83, 175, 151, 131,
, 120 218, 141, 206, 254,
, 38 28, 244, 172, 213,
, 206 128, 248, 156, 45,
, 40 204, 44, 169, 3,
, 201 162, 188, 16, 173,
, 62 192, 164, 96, 148,
, 83 91, 52, 244, 83,
, 175 149, 169, 82, 196,
, 151 199, 53, 177, 170,
, 131 1, 6, 0, 120,
, 218 170, 2, 238, 219,
, 141 241, 243, 172, 178,
, 206 104, 81, 159, 144
, 254
, 28
, 244
, 172
, 213
, 128
, 248
, 156
, 45
, 204
, 44
, 169
, 3
, 162
, 188
, 16
, 173
, 192
, 164
, 96
, 148
, 91
, 52
, 244
, 83
, 149
, 169
, 82
, 196
, 199
, 53
, 177
, 170
, 1
, 6
, 0
, 120
, 170
, 2
, 238
, 219
, 241
, 243
, 172
, 178
, 104
, 81
, 159
, 144
] :: [Word8] ] :: [Word8]
p <- generateWalletSeedPhrase let msg1 = genSaplingSpendingKey (word8ArrayToByteString hdseed1)
let s = getWalletSeed p let pmtaddress = genSaplingPaymentAddress msg1 --(word8ArrayToByteString hdseed1)
genSaplingPaymentAddress (fromMaybe "" s) 0 `shouldNotBe` Nothing let msgArr = BS.unpack pmtaddress
prop "Sapling receivers are valid" $ length msgArr `shouldBe` 43
forAll genSapArgs $ \(i) -> prop_SaplingReceiver i describe "Sapling Payment Find Address generation test" $ do
it "Call genSaplingFindPaymentAddress" $ do
let hdseed1 = [206, 61, 120, 38,
206, 40, 201, 62,
83, 175, 151, 131,
218, 141, 206, 254,
28, 244, 172, 213,
128, 248, 156, 45,
204, 44, 169, 3,
162, 188, 16, 173,
192, 164, 96, 148,
91, 52, 244, 83,
149, 169, 82, 196,
199, 53, 177, 170,
1, 6, 0, 120,
170, 2, 238, 219,
241, 243, 172, 178,
104, 81, 159, 144
] :: [Word8]
let msg1 = genSaplingSpendingKey (word8ArrayToByteString hdseed1)
let pmtaddress = genSaplingFindPaymentAddress msg1 0 --(word8ArrayToByteString hdseed1)
let msgArr = BS.unpack pmtaddress
length msgArr `shouldBe` 42
-- | Properties -- | Properties
prop_PhraseLength :: Int -> Property prop_PhraseLength :: Int -> Property
@ -758,14 +610,6 @@ prop_OrchardReceiver c i j =
let sk = genOrchardSpendingKey (fromMaybe "" s) c i let sk = genOrchardSpendingKey (fromMaybe "" s) c i
return $ genOrchardReceiver j (fromMaybe "" sk) =/= Nothing return $ genOrchardReceiver j (fromMaybe "" sk) =/= Nothing
prop_SaplingReceiver :: Int -> Property
prop_SaplingReceiver i =
ioProperty $ do
p <- generateWalletSeedPhrase
let s = getWalletSeed p
let sk = genSaplingSpendingKey (fromMaybe "" s)
return $ genSaplingPaymentAddress (fromMaybe "" sk) i =/= Nothing
-- | Generators -- | Generators
genOrcArgs :: Gen (CoinType, Int, Int) genOrcArgs :: Gen (CoinType, Int, Int)
genOrcArgs = do genOrcArgs = do
@ -773,7 +617,4 @@ genOrcArgs = do
j <- arbitrarySizedNatural j <- arbitrarySizedNatural
c <- elements [MainNetCoin, TestNetCoin, RegTestNetCoin] c <- elements [MainNetCoin, TestNetCoin, RegTestNetCoin]
return (c, i, j) return (c, i, j)
genSapArgs :: Gen Int
genSapArgs = choose (1, 50)
-- | Arbitrary instances -- | Arbitrary instances

View file

@ -5,7 +5,7 @@ cabal-version: 3.0
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
name: zcash-haskell name: zcash-haskell
version: 0.4.4.1 version: 0.4.4.0
synopsis: Utilities to interact with the Zcash blockchain synopsis: Utilities to interact with the Zcash blockchain
description: Please see the README on the repo at <https://git.vergara.tech/Vergara_Tech/zcash-haskell#readme> description: Please see the README on the repo at <https://git.vergara.tech/Vergara_Tech/zcash-haskell#readme>
category: Blockchain category: Blockchain