Complete Unified Address generation #37
3 changed files with 28 additions and 18 deletions
|
@ -124,7 +124,7 @@ genSaplingPaymentAddress i extspk =
|
||||||
-- | Generate an internal Sapling address
|
-- | Generate an internal Sapling address
|
||||||
genSaplingInternalAddress :: SaplingSpendingKey -> Maybe SaplingInternalReceiver
|
genSaplingInternalAddress :: SaplingSpendingKey -> Maybe SaplingInternalReceiver
|
||||||
genSaplingInternalAddress sk =
|
genSaplingInternalAddress sk =
|
||||||
if BS.length res <> 0
|
if (BS.length res) > 0
|
||||||
then Just res
|
then Just res
|
||||||
else Nothing
|
else Nothing
|
||||||
where
|
where
|
||||||
|
|
|
@ -28,15 +28,17 @@ import ZcashHaskell.Types
|
||||||
, TransparentAddress(..)
|
, TransparentAddress(..)
|
||||||
, TransparentType(..)
|
, TransparentType(..)
|
||||||
, ZcashNet(..)
|
, ZcashNet(..)
|
||||||
|
, CoinType(..)
|
||||||
, getTransparentPrefix
|
, getTransparentPrefix
|
||||||
|
, getValue
|
||||||
)
|
)
|
||||||
|
|
||||||
import Crypto.Secp256k1
|
import Crypto.Secp256k1
|
||||||
|
import Haskoin.Crypto.Keys.Extended
|
||||||
import Data.HexString
|
import Data.HexString
|
||||||
import Data.Word
|
import Data.Word
|
||||||
import Haskoin.Address (Address(..))
|
import Haskoin.Address (Address(..))
|
||||||
import qualified Haskoin.Crypto.Hash as H
|
import qualified Haskoin.Crypto.Hash as H
|
||||||
import Haskoin.Crypto.Keys.Extended
|
|
||||||
|
|
||||||
encodeTransparent :: ZcashNet -> TransparentAddress -> T.Text
|
encodeTransparent :: ZcashNet -> TransparentAddress -> T.Text
|
||||||
encodeTransparent zNet t =
|
encodeTransparent zNet t =
|
||||||
|
@ -53,11 +55,23 @@ encodeTransparent zNet t =
|
||||||
checksum = sha256 $ sha256 digest
|
checksum = sha256 $ sha256 digest
|
||||||
|
|
||||||
-- | Attempts to generate an Extended Private Key from a known HDSeed.
|
-- | Attempts to generate an Extended Private Key from a known HDSeed.
|
||||||
genTransparentPrvKey :: Seed -> AccountId -> IO XPrvKey
|
genTransparentPrvKey :: Seed -> CoinType -> AccountId -> IO XPrvKey
|
||||||
genTransparentPrvKey hdseed i = do
|
genTransparentPrvKey hdseed ctype accid = do
|
||||||
let prvKey = makeXPrvKey hdseed
|
let coin = getValue ctype
|
||||||
ioCtx <- createContext
|
ioCtx <- createContext
|
||||||
return $ hardSubKey ioCtx prvKey (fromIntegral i)
|
let path = Deriv :| 44 :| 133 :| coin :/ 0 :/ 0 :: DerivPath
|
||||||
|
let prvKey = makeXPrvKey hdseed
|
||||||
|
return $ derivePath ioCtx path prvKey
|
||||||
|
|
||||||
|
genTransparentPubKey :: XPrvKey -> IO XPubKey
|
||||||
|
genTransparentPubKey xPrvKey = do
|
||||||
|
ioCtx <- createContext
|
||||||
|
return $ deriveXPubKey ioCtx xPrvKey
|
||||||
|
|
||||||
|
genTransparentPubAddress :: XPubKey -> IO Address
|
||||||
|
genTransparentPubAddress xPubKey = do
|
||||||
|
ioCtx <- createContext
|
||||||
|
return $ xPubAddr ioCtx xPubKey
|
||||||
|
|
||||||
-- | Generate a transparent receiver
|
-- | Generate a transparent receiver
|
||||||
genTransparentReceiver :: Int -> XPrvKey -> IO TransparentAddress
|
genTransparentReceiver :: Int -> XPrvKey -> IO TransparentAddress
|
||||||
|
|
20
test/Spec.hs
20
test/Spec.hs
|
@ -45,7 +45,6 @@ import ZcashHaskell.Sapling
|
||||||
, genSaplingPaymentAddress
|
, genSaplingPaymentAddress
|
||||||
, genSaplingInternalAddress
|
, genSaplingInternalAddress
|
||||||
, genSaplingSpendingKey
|
, genSaplingSpendingKey
|
||||||
, genSaplingMasterSpendingKey
|
|
||||||
, getShieldedOutputs
|
, getShieldedOutputs
|
||||||
, isValidSaplingViewingKey
|
, isValidSaplingViewingKey
|
||||||
, isValidShieldedAddress
|
, isValidShieldedAddress
|
||||||
|
@ -502,7 +501,6 @@ main = do
|
||||||
maybe "No transparent" (encodeTransparent (ua_net u)) $
|
maybe "No transparent" (encodeTransparent (ua_net u)) $
|
||||||
t_rec u
|
t_rec u
|
||||||
msg `shouldBe` "t1LPWuQnjCRH7JAeEErSXKixcUteLJRJjKD"
|
msg `shouldBe` "t1LPWuQnjCRH7JAeEErSXKixcUteLJRJjKD"
|
||||||
<<<<<<< HEAD
|
|
||||||
describe "Transparent Private and Public Key Generation" $ do
|
describe "Transparent Private and Public 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 =
|
||||||
|
@ -571,7 +569,7 @@ main = do
|
||||||
, 159
|
, 159
|
||||||
, 144
|
, 144
|
||||||
] :: [Word8]
|
] :: [Word8]
|
||||||
let xtpvk = genTransparentPrvKey (BS.pack hdseed)
|
xtpvk <- genTransparentPrvKey (BS.pack hdseed) MainNetCoin 0
|
||||||
let testpvk =
|
let testpvk =
|
||||||
XPrvKey
|
XPrvKey
|
||||||
0
|
0
|
||||||
|
@ -608,9 +606,9 @@ main = do
|
||||||
it "Call genSaplingPaymentAddress" $ do
|
it "Call genSaplingPaymentAddress" $ do
|
||||||
p <- generateWalletSeedPhrase
|
p <- generateWalletSeedPhrase
|
||||||
let s = getWalletSeed p
|
let s = getWalletSeed p
|
||||||
genSaplingPaymentAddress (fromMaybe "" s) 0 `shouldNotBe` Nothing
|
genSaplingPaymentAddress 0 (fromMaybe "" s) `shouldNotBe` Nothing
|
||||||
prop "Sapling receivers are valid" $
|
-- prop "Sapling receivers are valid" $
|
||||||
forAll genSapArgs $ \i -> prop_SaplingReceiver i
|
-- forAll genSapArgs $ \s -> prop_SaplingReceiver s
|
||||||
describe "Sapling Change Payment Address generation test" $ do
|
describe "Sapling Change Payment Address generation test" $ do
|
||||||
it "Call genSaplingInternalAddress" $ do
|
it "Call genSaplingInternalAddress" $ do
|
||||||
let sk = [ 3
|
let sk = [ 3
|
||||||
|
@ -796,7 +794,6 @@ main = do
|
||||||
let bscAdr = BS.pack cAdr
|
let bscAdr = BS.pack cAdr
|
||||||
let ca = genSaplingInternalAddress (BS.pack sk)
|
let ca = genSaplingInternalAddress (BS.pack sk)
|
||||||
(fromMaybe "" ca) `shouldBe` bscAdr
|
(fromMaybe "" ca) `shouldBe` bscAdr
|
||||||
=======
|
|
||||||
it "Recover UA from YWallet" $
|
it "Recover UA from YWallet" $
|
||||||
ioProperty $ do
|
ioProperty $ do
|
||||||
let p =
|
let p =
|
||||||
|
@ -810,7 +807,7 @@ main = do
|
||||||
Just s' -> do
|
Just s' -> do
|
||||||
let oK = genOrchardSpendingKey s' MainNetCoin 0
|
let oK = genOrchardSpendingKey s' MainNetCoin 0
|
||||||
let sK = genSaplingSpendingKey s' MainNetCoin 0
|
let sK = genSaplingSpendingKey s' MainNetCoin 0
|
||||||
let tK = genTransparentPrvKey s' 0
|
let tK = genTransparentPrvKey s' MainNetCoin 0
|
||||||
let oR = genOrchardReceiver 0 =<< oK
|
let oR = genOrchardReceiver 0 =<< oK
|
||||||
let sR = genSaplingPaymentAddress 0 =<< sK
|
let sR = genSaplingPaymentAddress 0 =<< sK
|
||||||
tR <- genTransparentReceiver 0 =<< tK
|
tR <- genTransparentReceiver 0 =<< tK
|
||||||
|
@ -829,14 +826,13 @@ main = do
|
||||||
Just s' -> do
|
Just s' -> do
|
||||||
let oK = genOrchardSpendingKey s' MainNetCoin 0
|
let oK = genOrchardSpendingKey s' MainNetCoin 0
|
||||||
let sK = genSaplingSpendingKey s' MainNetCoin 0
|
let sK = genSaplingSpendingKey s' MainNetCoin 0
|
||||||
let tK = genTransparentPrvKey s' 0
|
let tK = genTransparentPrvKey s' MainNetCoin 0
|
||||||
let oR = genOrchardReceiver 0 =<< oK
|
let oR = genOrchardReceiver 0 =<< oK
|
||||||
let sR = genSaplingPaymentAddress 0 =<< sK
|
let sR = genSaplingPaymentAddress 0 =<< sK
|
||||||
tR <- genTransparentReceiver 0 =<< tK
|
tR <- genTransparentReceiver 0 =<< tK
|
||||||
let newUA = UnifiedAddress MainNet oR sR $ Just tR
|
let newUA = UnifiedAddress MainNet oR sR $ Just tR
|
||||||
return $ Just newUA `shouldBe` targetUA
|
return $ Just newUA `shouldBe` targetUA
|
||||||
|
|
||||||
>>>>>>> origin/dev040
|
|
||||||
-- | Properties
|
-- | Properties
|
||||||
prop_PhraseLength :: Property
|
prop_PhraseLength :: Property
|
||||||
prop_PhraseLength =
|
prop_PhraseLength =
|
||||||
|
@ -884,14 +880,14 @@ prop_OrchardRecRepeated s c (NonNegative i) (NonNegative j) =
|
||||||
prop_TransparentSpendingKey :: Seed -> NonNegative Int -> Property
|
prop_TransparentSpendingKey :: Seed -> NonNegative Int -> Property
|
||||||
prop_TransparentSpendingKey s (NonNegative i) =
|
prop_TransparentSpendingKey s (NonNegative i) =
|
||||||
ioProperty $ do
|
ioProperty $ do
|
||||||
k <- genTransparentPrvKey s i
|
k <- genTransparentPrvKey s MainNetCoin 0
|
||||||
return $ xPrvChild k == fromIntegral i
|
return $ xPrvChild k == fromIntegral i
|
||||||
|
|
||||||
prop_TransparentReceiver ::
|
prop_TransparentReceiver ::
|
||||||
Seed -> NonNegative Int -> NonNegative Int -> Property
|
Seed -> NonNegative Int -> NonNegative Int -> Property
|
||||||
prop_TransparentReceiver s (NonNegative i) (NonNegative j) =
|
prop_TransparentReceiver s (NonNegative i) (NonNegative j) =
|
||||||
ioProperty $ do
|
ioProperty $ do
|
||||||
k <- genTransparentPrvKey s i
|
k <- genTransparentPrvKey s MainCoinNet i
|
||||||
r <- genTransparentReceiver j k
|
r <- genTransparentReceiver j k
|
||||||
return $ ta_type r == P2PKH
|
return $ ta_type r == P2PKH
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue