{-# OPTIONS_GHC -Wno-orphans #-}

-- | QuickCheck 'Arbitrary' instances for wallet types.
--
-- 'Arbitrary' 'EncryptedKey' always produces v2 envelopes wrapped with the
-- empty passphrase so that tests can call passphrase-dependent operations
-- without tracking a per-key passphrase.
module Test.Cardano.Crypto.WalletHD.Arbitrary () where

import qualified Data.ByteString as BS
import System.IO.Unsafe (unsafePerformIO)
import Test.QuickCheck

import Test.Cardano.Base.Bytes (genByteString)

import Cardano.Crypto.WalletHD.Encrypted

instance Arbitrary DerivationScheme where
  arbitrary :: Gen DerivationScheme
arbitrary = [DerivationScheme] -> Gen DerivationScheme
forall a. HasCallStack => [a] -> Gen a
elements [DerivationScheme
DerivationScheme1, DerivationScheme
DerivationScheme2]

-- | Generates a v2-wrapped 'EncryptedKey' from a random 32-byte seed and
-- chain code, always encrypted with the empty passphrase.
instance Arbitrary EncryptedKey where
  arbitrary :: Gen EncryptedKey
arbitrary = do
    ByteString
seed <- Int -> Gen ByteString
genByteString Int
32
    ByteString
cc <- Int -> Gen ByteString
genByteString Int
32
    case IO (Either XPrvError EncryptedKey) -> Either XPrvError EncryptedKey
forall a. IO a -> a
unsafePerformIO (ByteString
-> ByteString -> ByteString -> IO (Either XPrvError EncryptedKey)
forall passphrase secret cc.
(ByteArrayAccess passphrase, ByteArrayAccess secret,
 ByteArrayAccess cc) =>
secret -> passphrase -> cc -> IO (Either XPrvError EncryptedKey)
encryptedCreate ByteString
seed (ByteString
BS.empty :: BS.ByteString) ByteString
cc) of
      Right EncryptedKey
k -> EncryptedKey -> Gen EncryptedKey
forall a. a -> Gen a
forall (f :: * -> *) a. Applicative f => a -> f a
pure EncryptedKey
k
      -- Approximately 50% of the time `encryptedCreate` will fail due to
      -- an invalid `cc`, since it is generated uniformly.
      -- It is OK to retry half the time.
      Left XPrvError
_ -> Gen EncryptedKey
forall a. Arbitrary a => Gen a
arbitrary