{-# LANGUAGE DataKinds          #-}
{-# LANGUAGE DeriveAnyClass     #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts   #-}
{-# LANGUAGE NamedFieldPuns     #-}
{-# LANGUAGE OverloadedStrings  #-}
{-# LANGUAGE TypeFamilies       #-}

{- Cardano wallet implementation for the emulator.
-}
module Ledger.CardanoWallet(
    MockWallet(..),
    -- * Enumerating wallets
    WalletNumber(..),
    fromWalletNumber,
    toWalletNumber,
    knownMockWallets,
    knownMockWallet,
    fromSeed,
    fromSeed',
    -- ** Keys
    mockWalletAddress,
    paymentPrivateKey,
    paymentPubKeyHash,
    paymentPubKey,
    stakingCredential,
    stakePubKeyHash,
    stakePubKey,
    knownAddresses,
    knownPaymentKeys,
    knownPaymentPublicKeys,
    knownPaymentPrivateKeys
    ) where

import Cardano.Crypto.Wallet qualified as Crypto
import Codec.Serialise (serialise)
import Crypto.Hash qualified as Crypto
import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson.Extras (encodeByteString)
import Data.ByteString qualified as BS
import Data.ByteString.Lazy qualified as BSL
import Data.Either (fromRight)
import Data.Hashable (Hashable (..))
import Data.List (findIndex)
import Data.Map qualified as Map
import Data.Maybe (fromMaybe)
import Data.Text qualified as T
import GHC.Generics (Generic)
import Ledger.Address (CardanoAddress, PaymentPrivateKey (PaymentPrivateKey, unPaymentPrivateKey),
                       PaymentPubKey (PaymentPubKey, unPaymentPubKey),
                       PaymentPubKeyHash (PaymentPubKeyHash, unPaymentPubKeyHash),
                       StakePubKey (StakePubKey, unStakePubKey), StakePubKeyHash (StakePubKeyHash, unStakePubKeyHash),
                       stakePubKeyHashCredential)
import Ledger.Crypto (PubKey (..))
import Ledger.Crypto qualified as Crypto
import Ledger.Test (testnet)
import Ledger.Tx.CardanoAPI.Internal qualified as Tx
import Plutus.V1.Ledger.Api (Address (Address), Credential (PubKeyCredential), StakingCredential (StakingHash))
import Plutus.V1.Ledger.Bytes (LedgerBytes (getLedgerBytes))
import Servant.API (FromHttpApiData, ToHttpApiData)

newtype MockPrivateKey = MockPrivateKey { MockPrivateKey -> XPrv
unMockPrivateKey :: Crypto.XPrv }

instance Show MockPrivateKey where
    show :: MockPrivateKey -> String
show = Text -> String
T.unpack (Text -> String)
-> (MockPrivateKey -> Text) -> MockPrivateKey -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
encodeByteString (ByteString -> Text)
-> (MockPrivateKey -> ByteString) -> MockPrivateKey -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XPrv -> ByteString
Crypto.unXPrv (XPrv -> ByteString)
-> (MockPrivateKey -> XPrv) -> MockPrivateKey -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockPrivateKey -> XPrv
unMockPrivateKey
instance Eq MockPrivateKey where
    (MockPrivateKey XPrv
l) == :: MockPrivateKey -> MockPrivateKey -> Bool
== (MockPrivateKey XPrv
r) = XPrv -> ByteString
Crypto.unXPrv XPrv
l ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== XPrv -> ByteString
Crypto.unXPrv XPrv
r
instance Ord MockPrivateKey where
    compare :: MockPrivateKey -> MockPrivateKey -> Ordering
compare (MockPrivateKey XPrv
l) (MockPrivateKey XPrv
r) = ByteString -> ByteString -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (XPrv -> ByteString
Crypto.unXPrv XPrv
l) (XPrv -> ByteString
Crypto.unXPrv XPrv
r)
instance Hashable MockPrivateKey where
    hashWithSalt :: Int -> MockPrivateKey -> Int
hashWithSalt Int
i = Int -> ByteString -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
i (ByteString -> Int)
-> (MockPrivateKey -> ByteString) -> MockPrivateKey -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XPrv -> ByteString
Crypto.unXPrv (XPrv -> ByteString)
-> (MockPrivateKey -> XPrv) -> MockPrivateKey -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockPrivateKey -> XPrv
unMockPrivateKey

-- | Emulated wallet with a key and a passphrase
data MockWallet =
    MockWallet
        { MockWallet -> Digest Blake2b_160
mwWalletId   :: Crypto.Digest Crypto.Blake2b_160
        , MockWallet -> MockPrivateKey
mwPaymentKey :: MockPrivateKey
        , MockWallet -> Maybe MockPrivateKey
mwStakeKey   :: Maybe MockPrivateKey
        , MockWallet -> Maybe String
mwPrintAs    :: Maybe String
        } deriving Int -> MockWallet -> ShowS
[MockWallet] -> ShowS
MockWallet -> String
(Int -> MockWallet -> ShowS)
-> (MockWallet -> String)
-> ([MockWallet] -> ShowS)
-> Show MockWallet
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MockWallet] -> ShowS
$cshowList :: [MockWallet] -> ShowS
show :: MockWallet -> String
$cshow :: MockWallet -> String
showsPrec :: Int -> MockWallet -> ShowS
$cshowsPrec :: Int -> MockWallet -> ShowS
Show

-- | Wrapper for config files and APIs
newtype WalletNumber = WalletNumber { WalletNumber -> Integer
getWallet :: Integer }
    deriving (Int -> WalletNumber -> ShowS
[WalletNumber] -> ShowS
WalletNumber -> String
(Int -> WalletNumber -> ShowS)
-> (WalletNumber -> String)
-> ([WalletNumber] -> ShowS)
-> Show WalletNumber
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WalletNumber] -> ShowS
$cshowList :: [WalletNumber] -> ShowS
show :: WalletNumber -> String
$cshow :: WalletNumber -> String
showsPrec :: Int -> WalletNumber -> ShowS
$cshowsPrec :: Int -> WalletNumber -> ShowS
Show, WalletNumber -> WalletNumber -> Bool
(WalletNumber -> WalletNumber -> Bool)
-> (WalletNumber -> WalletNumber -> Bool) -> Eq WalletNumber
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WalletNumber -> WalletNumber -> Bool
$c/= :: WalletNumber -> WalletNumber -> Bool
== :: WalletNumber -> WalletNumber -> Bool
$c== :: WalletNumber -> WalletNumber -> Bool
Eq, Eq WalletNumber
Eq WalletNumber
-> (WalletNumber -> WalletNumber -> Ordering)
-> (WalletNumber -> WalletNumber -> Bool)
-> (WalletNumber -> WalletNumber -> Bool)
-> (WalletNumber -> WalletNumber -> Bool)
-> (WalletNumber -> WalletNumber -> Bool)
-> (WalletNumber -> WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber -> WalletNumber)
-> Ord WalletNumber
WalletNumber -> WalletNumber -> Bool
WalletNumber -> WalletNumber -> Ordering
WalletNumber -> WalletNumber -> WalletNumber
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: WalletNumber -> WalletNumber -> WalletNumber
$cmin :: WalletNumber -> WalletNumber -> WalletNumber
max :: WalletNumber -> WalletNumber -> WalletNumber
$cmax :: WalletNumber -> WalletNumber -> WalletNumber
>= :: WalletNumber -> WalletNumber -> Bool
$c>= :: WalletNumber -> WalletNumber -> Bool
> :: WalletNumber -> WalletNumber -> Bool
$c> :: WalletNumber -> WalletNumber -> Bool
<= :: WalletNumber -> WalletNumber -> Bool
$c<= :: WalletNumber -> WalletNumber -> Bool
< :: WalletNumber -> WalletNumber -> Bool
$c< :: WalletNumber -> WalletNumber -> Bool
compare :: WalletNumber -> WalletNumber -> Ordering
$ccompare :: WalletNumber -> WalletNumber -> Ordering
$cp1Ord :: Eq WalletNumber
Ord, (forall x. WalletNumber -> Rep WalletNumber x)
-> (forall x. Rep WalletNumber x -> WalletNumber)
-> Generic WalletNumber
forall x. Rep WalletNumber x -> WalletNumber
forall x. WalletNumber -> Rep WalletNumber x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep WalletNumber x -> WalletNumber
$cfrom :: forall x. WalletNumber -> Rep WalletNumber x
Generic)
    deriving newtype (WalletNumber -> ByteString
WalletNumber -> Text
WalletNumber -> Builder
(WalletNumber -> Text)
-> (WalletNumber -> Builder)
-> (WalletNumber -> ByteString)
-> (WalletNumber -> Text)
-> ToHttpApiData WalletNumber
forall a.
(a -> Text)
-> (a -> Builder)
-> (a -> ByteString)
-> (a -> Text)
-> ToHttpApiData a
toQueryParam :: WalletNumber -> Text
$ctoQueryParam :: WalletNumber -> Text
toHeader :: WalletNumber -> ByteString
$ctoHeader :: WalletNumber -> ByteString
toEncodedUrlPiece :: WalletNumber -> Builder
$ctoEncodedUrlPiece :: WalletNumber -> Builder
toUrlPiece :: WalletNumber -> Text
$ctoUrlPiece :: WalletNumber -> Text
ToHttpApiData, ByteString -> Either Text WalletNumber
Text -> Either Text WalletNumber
(Text -> Either Text WalletNumber)
-> (ByteString -> Either Text WalletNumber)
-> (Text -> Either Text WalletNumber)
-> FromHttpApiData WalletNumber
forall a.
(Text -> Either Text a)
-> (ByteString -> Either Text a)
-> (Text -> Either Text a)
-> FromHttpApiData a
parseQueryParam :: Text -> Either Text WalletNumber
$cparseQueryParam :: Text -> Either Text WalletNumber
parseHeader :: ByteString -> Either Text WalletNumber
$cparseHeader :: ByteString -> Either Text WalletNumber
parseUrlPiece :: Text -> Either Text WalletNumber
$cparseUrlPiece :: Text -> Either Text WalletNumber
FromHttpApiData, Integer -> WalletNumber
WalletNumber -> WalletNumber
WalletNumber -> WalletNumber -> WalletNumber
(WalletNumber -> WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber)
-> (Integer -> WalletNumber)
-> Num WalletNumber
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> WalletNumber
$cfromInteger :: Integer -> WalletNumber
signum :: WalletNumber -> WalletNumber
$csignum :: WalletNumber -> WalletNumber
abs :: WalletNumber -> WalletNumber
$cabs :: WalletNumber -> WalletNumber
negate :: WalletNumber -> WalletNumber
$cnegate :: WalletNumber -> WalletNumber
* :: WalletNumber -> WalletNumber -> WalletNumber
$c* :: WalletNumber -> WalletNumber -> WalletNumber
- :: WalletNumber -> WalletNumber -> WalletNumber
$c- :: WalletNumber -> WalletNumber -> WalletNumber
+ :: WalletNumber -> WalletNumber -> WalletNumber
$c+ :: WalletNumber -> WalletNumber -> WalletNumber
Num, Int -> WalletNumber
WalletNumber -> Int
WalletNumber -> [WalletNumber]
WalletNumber -> WalletNumber
WalletNumber -> WalletNumber -> [WalletNumber]
WalletNumber -> WalletNumber -> WalletNumber -> [WalletNumber]
(WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber)
-> (Int -> WalletNumber)
-> (WalletNumber -> Int)
-> (WalletNumber -> [WalletNumber])
-> (WalletNumber -> WalletNumber -> [WalletNumber])
-> (WalletNumber -> WalletNumber -> [WalletNumber])
-> (WalletNumber -> WalletNumber -> WalletNumber -> [WalletNumber])
-> Enum WalletNumber
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: WalletNumber -> WalletNumber -> WalletNumber -> [WalletNumber]
$cenumFromThenTo :: WalletNumber -> WalletNumber -> WalletNumber -> [WalletNumber]
enumFromTo :: WalletNumber -> WalletNumber -> [WalletNumber]
$cenumFromTo :: WalletNumber -> WalletNumber -> [WalletNumber]
enumFromThen :: WalletNumber -> WalletNumber -> [WalletNumber]
$cenumFromThen :: WalletNumber -> WalletNumber -> [WalletNumber]
enumFrom :: WalletNumber -> [WalletNumber]
$cenumFrom :: WalletNumber -> [WalletNumber]
fromEnum :: WalletNumber -> Int
$cfromEnum :: WalletNumber -> Int
toEnum :: Int -> WalletNumber
$ctoEnum :: Int -> WalletNumber
pred :: WalletNumber -> WalletNumber
$cpred :: WalletNumber -> WalletNumber
succ :: WalletNumber -> WalletNumber
$csucc :: WalletNumber -> WalletNumber
Enum, Num WalletNumber
Ord WalletNumber
Num WalletNumber
-> Ord WalletNumber
-> (WalletNumber -> Rational)
-> Real WalletNumber
WalletNumber -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: WalletNumber -> Rational
$ctoRational :: WalletNumber -> Rational
$cp2Real :: Ord WalletNumber
$cp1Real :: Num WalletNumber
Real, Enum WalletNumber
Real WalletNumber
Real WalletNumber
-> Enum WalletNumber
-> (WalletNumber -> WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber -> WalletNumber)
-> (WalletNumber -> WalletNumber -> (WalletNumber, WalletNumber))
-> (WalletNumber -> WalletNumber -> (WalletNumber, WalletNumber))
-> (WalletNumber -> Integer)
-> Integral WalletNumber
WalletNumber -> Integer
WalletNumber -> WalletNumber -> (WalletNumber, WalletNumber)
WalletNumber -> WalletNumber -> WalletNumber
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: WalletNumber -> Integer
$ctoInteger :: WalletNumber -> Integer
divMod :: WalletNumber -> WalletNumber -> (WalletNumber, WalletNumber)
$cdivMod :: WalletNumber -> WalletNumber -> (WalletNumber, WalletNumber)
quotRem :: WalletNumber -> WalletNumber -> (WalletNumber, WalletNumber)
$cquotRem :: WalletNumber -> WalletNumber -> (WalletNumber, WalletNumber)
mod :: WalletNumber -> WalletNumber -> WalletNumber
$cmod :: WalletNumber -> WalletNumber -> WalletNumber
div :: WalletNumber -> WalletNumber -> WalletNumber
$cdiv :: WalletNumber -> WalletNumber -> WalletNumber
rem :: WalletNumber -> WalletNumber -> WalletNumber
$crem :: WalletNumber -> WalletNumber -> WalletNumber
quot :: WalletNumber -> WalletNumber -> WalletNumber
$cquot :: WalletNumber -> WalletNumber -> WalletNumber
$cp2Integral :: Enum WalletNumber
$cp1Integral :: Real WalletNumber
Integral)
    deriving anyclass (Value -> Parser [WalletNumber]
Value -> Parser WalletNumber
(Value -> Parser WalletNumber)
-> (Value -> Parser [WalletNumber]) -> FromJSON WalletNumber
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [WalletNumber]
$cparseJSONList :: Value -> Parser [WalletNumber]
parseJSON :: Value -> Parser WalletNumber
$cparseJSON :: Value -> Parser WalletNumber
FromJSON, [WalletNumber] -> Encoding
[WalletNumber] -> Value
WalletNumber -> Encoding
WalletNumber -> Value
(WalletNumber -> Value)
-> (WalletNumber -> Encoding)
-> ([WalletNumber] -> Value)
-> ([WalletNumber] -> Encoding)
-> ToJSON WalletNumber
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [WalletNumber] -> Encoding
$ctoEncodingList :: [WalletNumber] -> Encoding
toJSONList :: [WalletNumber] -> Value
$ctoJSONList :: [WalletNumber] -> Value
toEncoding :: WalletNumber -> Encoding
$ctoEncoding :: WalletNumber -> Encoding
toJSON :: WalletNumber -> Value
$ctoJSON :: WalletNumber -> Value
ToJSON)

fromWalletNumber :: WalletNumber -> MockWallet
fromWalletNumber :: WalletNumber -> MockWallet
fromWalletNumber (WalletNumber Integer
i) = (ByteString -> MockWallet
fromSeed' (ByteString -> ByteString
BSL.toStrict (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ Integer -> ByteString
forall a. Serialise a => a -> ByteString
serialise Integer
i)) { mwPrintAs :: Maybe String
mwPrintAs = String -> Maybe String
forall a. a -> Maybe a
Just (Integer -> String
forall a. Show a => a -> String
show Integer
i) }

fromSeed :: BS.ByteString -> Crypto.Passphrase -> MockWallet
fromSeed :: ByteString -> Passphrase -> MockWallet
fromSeed ByteString
bs Passphrase
passPhrase = (ByteString -> XPrv) -> ByteString -> MockWallet
fromSeedInternal ((ByteString -> Passphrase -> XPrv)
-> Passphrase -> ByteString -> XPrv
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString -> Passphrase -> XPrv
Crypto.generateFromSeed Passphrase
passPhrase) ByteString
bs

fromSeed' :: BS.ByteString -> MockWallet
fromSeed' :: ByteString -> MockWallet
fromSeed' = (ByteString -> XPrv) -> ByteString -> MockWallet
fromSeedInternal ByteString -> XPrv
Crypto.generateFromSeed'

fromSeedInternal :: (BS.ByteString -> Crypto.XPrv) -> BS.ByteString -> MockWallet
fromSeedInternal :: (ByteString -> XPrv) -> ByteString -> MockWallet
fromSeedInternal ByteString -> XPrv
seedGen ByteString
bs = MockWallet :: Digest Blake2b_160
-> MockPrivateKey
-> Maybe MockPrivateKey
-> Maybe String
-> MockWallet
MockWallet{Digest Blake2b_160
mwWalletId :: Digest Blake2b_160
mwWalletId :: Digest Blake2b_160
mwWalletId, MockPrivateKey
mwPaymentKey :: MockPrivateKey
mwPaymentKey :: MockPrivateKey
mwPaymentKey, Maybe MockPrivateKey
forall a. Maybe a
mwStakeKey :: forall a. Maybe a
mwStakeKey :: Maybe MockPrivateKey
mwStakeKey, mwPrintAs :: Maybe String
mwPrintAs = Maybe String
forall a. Maybe a
Nothing} where
    missing :: Int
missing = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int
32 Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
BS.length ByteString
bs)
    bs' :: ByteString
bs' = ByteString
bs ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> Int -> Word8 -> ByteString
BS.replicate Int
missing Word8
0
    k :: XPrv
k = ByteString -> XPrv
seedGen ByteString
bs'
    mwWalletId :: Digest Blake2b_160
mwWalletId =
        Digest Blake2b_160
-> Maybe (Digest Blake2b_160) -> Digest Blake2b_160
forall a. a -> Maybe a -> a
fromMaybe (String -> Digest Blake2b_160
forall a. HasCallStack => String -> a
error String
"Ledger.CardanoWallet.fromSeed: digestFromByteString")
        (Maybe (Digest Blake2b_160) -> Digest Blake2b_160)
-> Maybe (Digest Blake2b_160) -> Digest Blake2b_160
forall a b. (a -> b) -> a -> b
$ Digest Blake2b_160 -> Maybe (Digest Blake2b_160)
forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
Crypto.digestFromByteString
        (Digest Blake2b_160 -> Maybe (Digest Blake2b_160))
-> Digest Blake2b_160 -> Maybe (Digest Blake2b_160)
forall a b. (a -> b) -> a -> b
$ Blake2b_160 -> BuiltinByteString -> Digest Blake2b_160
forall ba alg.
(ByteArrayAccess ba, HashAlgorithm alg) =>
alg -> ba -> Digest alg
Crypto.hashWith Blake2b_160
Crypto.Blake2b_160
        (BuiltinByteString -> Digest Blake2b_160)
-> BuiltinByteString -> Digest Blake2b_160
forall a b. (a -> b) -> a -> b
$ LedgerBytes -> BuiltinByteString
getLedgerBytes
        (LedgerBytes -> BuiltinByteString)
-> LedgerBytes -> BuiltinByteString
forall a b. (a -> b) -> a -> b
$ PubKey -> LedgerBytes
getPubKey
        (PubKey -> LedgerBytes) -> PubKey -> LedgerBytes
forall a b. (a -> b) -> a -> b
$ XPrv -> PubKey
Crypto.toPublicKey XPrv
k
    mwPaymentKey :: MockPrivateKey
mwPaymentKey = XPrv -> MockPrivateKey
MockPrivateKey XPrv
k
    mwStakeKey :: Maybe a
mwStakeKey = Maybe a
forall a. Maybe a
Nothing

toWalletNumber :: MockWallet -> WalletNumber
toWalletNumber :: MockWallet -> WalletNumber
toWalletNumber MockWallet{mwWalletId :: MockWallet -> Digest Blake2b_160
mwWalletId=Digest Blake2b_160
w} =
    WalletNumber -> (Int -> WalletNumber) -> Maybe Int -> WalletNumber
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> WalletNumber
forall a. HasCallStack => String -> a
error String
"Ledger.CardanoWallet.toWalletNumber: not a known wallet")
          (Integer -> WalletNumber
WalletNumber (Integer -> WalletNumber)
-> (Int -> Integer) -> Int -> WalletNumber
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Integer) -> (Int -> Int) -> Int -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
forall a. Enum a => a -> a
succ)
          (Maybe Int -> WalletNumber) -> Maybe Int -> WalletNumber
forall a b. (a -> b) -> a -> b
$ (MockWallet -> Bool) -> [MockWallet] -> Maybe Int
forall a. (a -> Bool) -> [a] -> Maybe Int
findIndex (Digest Blake2b_160 -> Digest Blake2b_160 -> Bool
forall a. Eq a => a -> a -> Bool
(==) Digest Blake2b_160
w (Digest Blake2b_160 -> Bool)
-> (MockWallet -> Digest Blake2b_160) -> MockWallet -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockWallet -> Digest Blake2b_160
mwWalletId) [MockWallet]
knownMockWallets

-- | The wallets used in mockchain simulations by default. There are
--   ten wallets by default.
knownMockWallets :: [MockWallet]
knownMockWallets :: [MockWallet]
knownMockWallets = WalletNumber -> MockWallet
fromWalletNumber (WalletNumber -> MockWallet)
-> (Integer -> WalletNumber) -> Integer -> MockWallet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> WalletNumber
WalletNumber (Integer -> MockWallet) -> [Integer] -> [MockWallet]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Integer
1..Integer
10]

-- | Get a known wallet from an @Integer@ indexed from 1 to 10.
knownMockWallet :: Integer -> MockWallet
knownMockWallet :: Integer -> MockWallet
knownMockWallet = ([MockWallet]
knownMockWallets [MockWallet] -> Int -> MockWallet
forall a. [a] -> Int -> a
!!) (Int -> MockWallet) -> (Integer -> Int) -> Integer -> MockWallet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
forall a. Enum a => a -> a
pred (Int -> Int) -> (Integer -> Int) -> Integer -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Int
forall a. Num a => Integer -> a
fromInteger

{- | A mock cardano address for the testnet network.
 -}
mockWalletAddress :: MockWallet -> CardanoAddress
mockWalletAddress :: MockWallet -> CardanoAddress
mockWalletAddress =
    CardanoAddress
-> Either ToCardanoError CardanoAddress -> CardanoAddress
forall b a. b -> Either a b -> b
fromRight (String -> CardanoAddress
forall a. HasCallStack => String -> a
error String
"mock wallet is invalid")
       (Either ToCardanoError CardanoAddress -> CardanoAddress)
-> (MockWallet -> Either ToCardanoError CardanoAddress)
-> MockWallet
-> CardanoAddress
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NetworkId -> Address -> Either ToCardanoError CardanoAddress
Tx.toCardanoAddressInEra NetworkId
testnet
       (Address -> Either ToCardanoError CardanoAddress)
-> (MockWallet -> Address)
-> MockWallet
-> Either ToCardanoError CardanoAddress
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockWallet -> Address
plutusAddress
    where
    plutusAddress :: MockWallet -> Address
plutusAddress MockWallet
mw =
        Credential -> Maybe StakingCredential -> Address
Address (PubKeyHash -> Credential
PubKeyCredential (PubKeyHash -> Credential) -> PubKeyHash -> Credential
forall a b. (a -> b) -> a -> b
$ PaymentPubKeyHash -> PubKeyHash
unPaymentPubKeyHash (PaymentPubKeyHash -> PubKeyHash)
-> PaymentPubKeyHash -> PubKeyHash
forall a b. (a -> b) -> a -> b
$ MockWallet -> PaymentPubKeyHash
paymentPubKeyHash MockWallet
mw)
                (Credential -> StakingCredential
StakingHash (Credential -> StakingCredential)
-> (StakePubKeyHash -> Credential)
-> StakePubKeyHash
-> StakingCredential
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PubKeyHash -> Credential
PubKeyCredential (PubKeyHash -> Credential)
-> (StakePubKeyHash -> PubKeyHash) -> StakePubKeyHash -> Credential
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StakePubKeyHash -> PubKeyHash
unStakePubKeyHash (StakePubKeyHash -> StakingCredential)
-> Maybe StakePubKeyHash -> Maybe StakingCredential
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MockWallet -> Maybe StakePubKeyHash
stakePubKeyHash MockWallet
mw)

-- | Mock wallet's private key
paymentPrivateKey :: MockWallet -> PaymentPrivateKey
paymentPrivateKey :: MockWallet -> PaymentPrivateKey
paymentPrivateKey = XPrv -> PaymentPrivateKey
PaymentPrivateKey (XPrv -> PaymentPrivateKey)
-> (MockWallet -> XPrv) -> MockWallet -> PaymentPrivateKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockPrivateKey -> XPrv
unMockPrivateKey (MockPrivateKey -> XPrv)
-> (MockWallet -> MockPrivateKey) -> MockWallet -> XPrv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockWallet -> MockPrivateKey
mwPaymentKey

-- | The mock wallet's public key hash
paymentPubKeyHash :: MockWallet -> PaymentPubKeyHash
paymentPubKeyHash :: MockWallet -> PaymentPubKeyHash
paymentPubKeyHash = PubKeyHash -> PaymentPubKeyHash
PaymentPubKeyHash (PubKeyHash -> PaymentPubKeyHash)
-> (MockWallet -> PubKeyHash) -> MockWallet -> PaymentPubKeyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PubKey -> PubKeyHash
Crypto.pubKeyHash (PubKey -> PubKeyHash)
-> (MockWallet -> PubKey) -> MockWallet -> PubKeyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PaymentPubKey -> PubKey
unPaymentPubKey (PaymentPubKey -> PubKey)
-> (MockWallet -> PaymentPubKey) -> MockWallet -> PubKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockWallet -> PaymentPubKey
paymentPubKey

-- | The mock wallet's payment public key
paymentPubKey :: MockWallet -> PaymentPubKey
paymentPubKey :: MockWallet -> PaymentPubKey
paymentPubKey = PubKey -> PaymentPubKey
PaymentPubKey (PubKey -> PaymentPubKey)
-> (MockWallet -> PubKey) -> MockWallet -> PaymentPubKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XPrv -> PubKey
Crypto.toPublicKey (XPrv -> PubKey) -> (MockWallet -> XPrv) -> MockWallet -> PubKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockPrivateKey -> XPrv
unMockPrivateKey (MockPrivateKey -> XPrv)
-> (MockWallet -> MockPrivateKey) -> MockWallet -> XPrv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockWallet -> MockPrivateKey
mwPaymentKey

-- | The mock wallet's stake public key hash
stakePubKeyHash :: MockWallet -> Maybe StakePubKeyHash
stakePubKeyHash :: MockWallet -> Maybe StakePubKeyHash
stakePubKeyHash MockWallet
w = PubKeyHash -> StakePubKeyHash
StakePubKeyHash (PubKeyHash -> StakePubKeyHash)
-> (StakePubKey -> PubKeyHash) -> StakePubKey -> StakePubKeyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PubKey -> PubKeyHash
Crypto.pubKeyHash (PubKey -> PubKeyHash)
-> (StakePubKey -> PubKey) -> StakePubKey -> PubKeyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StakePubKey -> PubKey
unStakePubKey (StakePubKey -> StakePubKeyHash)
-> Maybe StakePubKey -> Maybe StakePubKeyHash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MockWallet -> Maybe StakePubKey
stakePubKey MockWallet
w

-- | The mock wallet's stake public key
stakePubKey :: MockWallet -> Maybe StakePubKey
stakePubKey :: MockWallet -> Maybe StakePubKey
stakePubKey MockWallet
w = PubKey -> StakePubKey
StakePubKey (PubKey -> StakePubKey)
-> (MockPrivateKey -> PubKey) -> MockPrivateKey -> StakePubKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XPrv -> PubKey
Crypto.toPublicKey (XPrv -> PubKey)
-> (MockPrivateKey -> XPrv) -> MockPrivateKey -> PubKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockPrivateKey -> XPrv
unMockPrivateKey (MockPrivateKey -> StakePubKey)
-> Maybe MockPrivateKey -> Maybe StakePubKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MockWallet -> Maybe MockPrivateKey
mwStakeKey MockWallet
w

-- | The mock wallet's staking credentials
stakingCredential :: MockWallet -> Maybe StakingCredential
stakingCredential :: MockWallet -> Maybe StakingCredential
stakingCredential = (StakePubKeyHash -> StakingCredential)
-> Maybe StakePubKeyHash -> Maybe StakingCredential
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap StakePubKeyHash -> StakingCredential
stakePubKeyHashCredential (Maybe StakePubKeyHash -> Maybe StakingCredential)
-> (MockWallet -> Maybe StakePubKeyHash)
-> MockWallet
-> Maybe StakingCredential
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MockWallet -> Maybe StakePubKeyHash
stakePubKeyHash

knownPaymentPublicKeys :: [PaymentPubKey]
knownPaymentPublicKeys :: [PaymentPubKey]
knownPaymentPublicKeys =
    PubKey -> PaymentPubKey
PaymentPubKey (PubKey -> PaymentPubKey)
-> (PaymentPrivateKey -> PubKey)
-> PaymentPrivateKey
-> PaymentPubKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XPrv -> PubKey
Crypto.toPublicKey (XPrv -> PubKey)
-> (PaymentPrivateKey -> XPrv) -> PaymentPrivateKey -> PubKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PaymentPrivateKey -> XPrv
unPaymentPrivateKey (PaymentPrivateKey -> PaymentPubKey)
-> [PaymentPrivateKey] -> [PaymentPubKey]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PaymentPrivateKey]
knownPaymentPrivateKeys

knownPaymentKeys :: Map.Map PaymentPubKey PaymentPrivateKey
knownPaymentKeys :: Map PaymentPubKey PaymentPrivateKey
knownPaymentKeys = [(PaymentPubKey, PaymentPrivateKey)]
-> Map PaymentPubKey PaymentPrivateKey
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(PaymentPubKey, PaymentPrivateKey)]
 -> Map PaymentPubKey PaymentPrivateKey)
-> [(PaymentPubKey, PaymentPrivateKey)]
-> Map PaymentPubKey PaymentPrivateKey
forall a b. (a -> b) -> a -> b
$ (PaymentPrivateKey -> (PaymentPubKey, PaymentPrivateKey))
-> [PaymentPrivateKey] -> [(PaymentPubKey, PaymentPrivateKey)]
forall a b. (a -> b) -> [a] -> [b]
map
    (\PaymentPrivateKey
k -> (PubKey -> PaymentPubKey
PaymentPubKey (PubKey -> PaymentPubKey) -> PubKey -> PaymentPubKey
forall a b. (a -> b) -> a -> b
$ XPrv -> PubKey
Crypto.toPublicKey (XPrv -> PubKey) -> XPrv -> PubKey
forall a b. (a -> b) -> a -> b
$ PaymentPrivateKey -> XPrv
unPaymentPrivateKey PaymentPrivateKey
k, PaymentPrivateKey
k)) [PaymentPrivateKey]
knownPaymentPrivateKeys

knownPaymentPrivateKeys :: [PaymentPrivateKey]
knownPaymentPrivateKeys :: [PaymentPrivateKey]
knownPaymentPrivateKeys = MockWallet -> PaymentPrivateKey
paymentPrivateKey (MockWallet -> PaymentPrivateKey)
-> [MockWallet] -> [PaymentPrivateKey]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [MockWallet]
knownMockWallets

knownAddresses :: [CardanoAddress]
knownAddresses :: [CardanoAddress]
knownAddresses = MockWallet -> CardanoAddress
mockWalletAddress (MockWallet -> CardanoAddress) -> [MockWallet] -> [CardanoAddress]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [MockWallet]
knownMockWallets