Compare commits

...

3 commits

10 changed files with 324 additions and 254 deletions

View file

@ -19,6 +19,7 @@ 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,7 +1314,6 @@ 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,7 +17,6 @@ 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,15 +24,23 @@ use haskell_ffi::{
use zip32; use zip32;
use zcash_primitives::{ use zcash_primitives::{
zip32::Scope as SaplingScope, zip32::{
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::PreparedIncomingViewingKey as SaplingPreparedIncomingViewingKey, keys::{
PreparedIncomingViewingKey as SaplingPreparedIncomingViewingKey,
ExpandedSpendingKey,
FullViewingKey as SaplingFullViewingKey
},
note_encryption::SaplingDomain note_encryption::SaplingDomain
}, },
transaction::Transaction, transaction::Transaction,
@ -49,13 +57,12 @@ use zcash_address::{
ZcashAddress ZcashAddress
}; };
use zcash_client_backend::keys::{ use zcash_client_backend::keys::sapling::{
sapling, ExtendedFullViewingKey,
sapling::ExtendedFullViewingKey, ExtendedSpendingKey
sapling::ExtendedSpendingKey}; };
use zcash_primitives::zip32::{ AccountId, DiversifierIndex }; use zcash_primitives::zip32::{ AccountId, DiversifierIndex };
use std::slice;
use orchard::{ use orchard::{
Action, Action,
@ -624,7 +631,6 @@ 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
@ -634,8 +640,7 @@ 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;
println!("Seed : {:?}\n", &seedu8); let extsk: ExtendedSpendingKey = ExtendedSpendingKey::master(&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);
} }
@ -645,94 +650,25 @@ 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,
// divIx: u32, div_ix: u32,
out: *mut u8, out: *mut u8,
out_len: &mut usize out_len: &mut usize
){ ){
// println!("Starting paymentAddress generation...."); let extspk: Vec<u8> = marshall_from_haskell_var(extspk, extspk_len, RW);
let extspkb: Vec<u8> = marshall_from_haskell_var(extspk, extspk_len, RW); let expsk = ExpandedSpendingKey::from_spending_key(&extspk);
if ( extspkb.len() != 169 ) { let fvk = SaplingFullViewingKey::from_expanded_spending_key(&expsk);
// invalid ExtendedSpenndingKey Array length let dk = DiversifierKey::master(&extspk);
println!("Invalid ExtendedSpendingKey...."); let result = sapling_find_address(&fvk, &dk, DiversifierIndex::from(div_ix));
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,14 +141,7 @@ import ZcashHaskell.Types
-> `()' -> `()'
#} #}
{# fun unsafe rust_wrapper_sapling_paymentaddress as rustWrapperPaymentAddress {# fun unsafe rust_wrapper_sapling_paymentaddress as rustWrapperSaplingPaymentAddress
{ 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,15 +21,13 @@ 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
@ -37,16 +35,18 @@ import Foreign.Rust.Marshall.Variable
, withPureBorshVarBuffer , withPureBorshVarBuffer
) )
import ZcashHaskell.Types import ZcashHaskell.Types
( DecodedNote(..) ( AccountId
, CoinType
, DecodedNote(..)
, RawData(..) , RawData(..)
, RawTxResponse(..) , RawTxResponse(..)
, SaplingSKeyParams(..) , SaplingReceiver
, SaplingSpendingKey(..)
, Seed(..)
, ShieldedOutput(..) , ShieldedOutput(..)
, decodeHexText , decodeHexText
, AccountId
, CoinType
) )
import ZcashHaskell.Utils import ZcashHaskell.Utils (decodeBech32)
-- | 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,22 +92,25 @@ 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 SpendinKey using a HDSeed, a Coin Type and an Account ID
genSaplingSpendingKey :: BS.ByteString -> BS.ByteString
genSaplingSpendingKey seed = do
let res = withPureBorshVarBuffer (rustWrapperSaplingSpendingkey seed )
res
--
-- | Attempts to generate a sapling Payment Address using an ExtendedSpendingKey
genSaplingPaymentAddress :: BS.ByteString -> BS.ByteString
genSaplingPaymentAddress extspk = do
let pmtaddress = withPureBorshVarBuffer (rustWrapperPaymentAddress extspk )
pmtaddress
-- --
-- | Attempts to generate a sapling Payment Address using an ExtendedSpendingKey -- | Attempts to obtain a sapling SpendingKey using a HDSeed
genSaplingFindPaymentAddress :: BS.ByteString -> Word32 -> BS.ByteString genSaplingSpendingKey :: Seed -> Maybe SaplingSpendingKey
genSaplingFindPaymentAddress extspk divIx = do genSaplingSpendingKey seed = do
let pmtaddress = withPureBorshVarBuffer (rustWrapperFindPaymentAddress extspk divIx) if BS.length res == 196
pmtaddress then Just res
else Nothing
where
res = withPureBorshVarBuffer (rustWrapperSaplingSpendingkey seed)
--
-- | Attempts to generate a sapling Payment Address using an ExtendedSpendingKey and a Diversifier Index
genSaplingPaymentAddress :: SaplingSpendingKey -> Int -> Maybe SaplingReceiver
genSaplingPaymentAddress extspk i =
if BS.length res == 43
then Just res
else Nothing
where
res =
withPureBorshVarBuffer
(rustWrapperSaplingPaymentAddress extspk (fromIntegral i))

View file

@ -346,16 +346,6 @@ 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,13 +88,3 @@ 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,19 +41,21 @@ 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
( BlockResponse(..) ( AccountId
, BlockResponse(..)
, CoinType(..) , CoinType(..)
, CoinType
, DecodedNote(..) , DecodedNote(..)
, OrchardAction(..) , OrchardAction(..)
, Phrase(..) , Phrase(..)
@ -63,20 +65,17 @@ import ZcashHaskell.Types
, UnifiedAddress(..) , UnifiedAddress(..)
, UnifiedFullViewingKey(..) , UnifiedFullViewingKey(..)
, decodeHexText , decodeHexText
, AccountId
, CoinType
, getValue , getValue
) )
import ZcashHaskell.Utils import ZcashHaskell.Utils
import Foreign.C.Types
import Data.Word import Data.Word
import Foreign.C.Types
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
@ -484,102 +483,251 @@ 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 = [206, 61, 120, 38, let hdseed =
206, 40, 201, 62, [ 206
83, 175, 151, 131, , 61
218, 141, 206, 254, , 120
28, 244, 172, 213, , 38
128, 248, 156, 45, , 206
204, 44, 169, 3, , 40
162, 188, 16, 173, , 201
192, 164, 96, 148, , 62
91, 52, 244, 83, , 83
149, 169, 82, 196, , 175
199, 53, 177, 170, , 151
1, 6, 0, 120, , 131
170, 2, 238, 219, , 218
241, 243, 172, 178, , 141
104, 81, 159, 144 , 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] ] :: [Word8]
let xtpvk = genTransparentPrvKey (word8ArrayToByteString hdseed) let xtpvk = genTransparentPrvKey (BS.pack hdseed)
let testpvk = XPrvKey 0 "0000000000" 0 "fb5b9b89d3e9dfdebeaabd15de8fbc7e9a140b7f2de2b4034c2573425d39aceb" "46aa0cd24a6e05709591426a4e682dd5406de4e75a39c0f410ee790403880943" let testpvk =
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 = XPrvKey 0 "0000000000" 0 "fb5b9b89d3e9dfdebeaabd15de8fbc7e9a140b7f2de2b4034c2573425d39aceb" "46aa0cd24a6e05709591426a4e682dd5406de4e75a39c0f410ee790403880943" let testpvk =
let testpbk = XPubKey 0 "00000000" 0 "fb5b9b89d3e9dfdebeaabd15de8fbc7e9a140b7f2de2b4034c2573425d39aceb" "279bda9c704f6da479cedb12c7cf773b3a348569dc1cfa6002526bad67674fd737b84a2bdb1199ecab1c9fed1b9a38aba5ba19259c1510d733a2376118515cd8" XPrvKey
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
it "Call function with parameters" $ do let hdseed =
let hdseed = [206, 61, 120, 38, BS.pack $
206, 40, 201, 62, [ 206
83, 175, 151, 131, , 61
218, 141, 206, 254, , 120
28, 244, 172, 213, , 38
128, 248, 156, 45, , 206
204, 44, 169, 3, , 40
162, 188, 16, 173, , 201
192, 164, 96, 148, , 62
91, 52, 244, 83, , 83
149, 169, 82, 196, , 175
199, 53, 177, 170, , 151
1, 6, 0, 120, , 131
170, 2, 238, 219, , 218
241, 243, 172, 178, , 141
104, 81, 159, 144 , 206
] :: [Word8] , 254
let msg = genSaplingSpendingKey (word8ArrayToByteString hdseed) , 28
let msgArr = BS.unpack msg , 244
length msgArr `shouldBe` 169 , 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
]
--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 = [206, 61, 120, 38, let hdseed1 =
206, 40, 201, 62, [ 206
83, 175, 151, 131, , 61
218, 141, 206, 254, , 120
28, 244, 172, 213, , 38
128, 248, 156, 45, , 206
204, 44, 169, 3, , 40
162, 188, 16, 173, , 201
192, 164, 96, 148, , 62
91, 52, 244, 83, , 83
149, 169, 82, 196, , 175
199, 53, 177, 170, , 151
1, 6, 0, 120, , 131
170, 2, 238, 219, , 218
241, 243, 172, 178, , 141
104, 81, 159, 144 , 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] ] :: [Word8]
let msg1 = genSaplingSpendingKey (word8ArrayToByteString hdseed1) p <- generateWalletSeedPhrase
let pmtaddress = genSaplingPaymentAddress msg1 --(word8ArrayToByteString hdseed1) let s = getWalletSeed p
let msgArr = BS.unpack pmtaddress genSaplingPaymentAddress (fromMaybe "" s) 0 `shouldNotBe` Nothing
length msgArr `shouldBe` 43 prop "Sapling receivers are valid" $
describe "Sapling Payment Find Address generation test" $ do forAll genSapArgs $ \(i) -> prop_SaplingReceiver i
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
@ -610,6 +758,14 @@ 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
@ -617,4 +773,7 @@ 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.0 version: 0.4.4.1
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