module Cardano.Chain.UTxO.GenesisUTxO
  ( genesisUtxo,
  )
where

import Cardano.Chain.Common (Address, Lovelace, makeRedeemAddress)
import Cardano.Chain.Common.NetworkMagic (NetworkMagic, makeNetworkMagic)
import Cardano.Chain.Genesis (unGenesisAvvmBalances, unGenesisNonAvvmBalances)
import qualified Cardano.Chain.Genesis as Genesis
import Cardano.Chain.UTxO.UTxO (UTxO)
import qualified Cardano.Chain.UTxO.UTxO as UTxO
import Cardano.Crypto (fromCompactRedeemVerificationKey)
import Cardano.Prelude
import qualified Data.Map.Strict as M

-- | Create initial 'UTxO' from balances defined in the genesis config
genesisUtxo :: Genesis.Config -> UTxO
genesisUtxo :: Config -> UTxO
genesisUtxo Config
config = [(Address, Lovelace)] -> UTxO
UTxO.fromBalances [(Address, Lovelace)]
balances
  where
    balances :: [(Address, Lovelace)]
    balances :: [(Address, Lovelace)]
balances = [(Address, Lovelace)]
avvmBalances [(Address, Lovelace)]
-> [(Address, Lovelace)] -> [(Address, Lovelace)]
forall a. Semigroup a => a -> a -> a
<> [(Address, Lovelace)]
nonAvvmBalances

    avvmBalances :: [(Address, Lovelace)]
    avvmBalances :: [(Address, Lovelace)]
avvmBalances =
      (CompactRedeemVerificationKey -> Address)
-> (CompactRedeemVerificationKey, Lovelace) -> (Address, Lovelace)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (NetworkMagic -> RedeemVerificationKey -> Address
makeRedeemAddress NetworkMagic
networkMagic (RedeemVerificationKey -> Address)
-> (CompactRedeemVerificationKey -> RedeemVerificationKey)
-> CompactRedeemVerificationKey
-> Address
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. CompactRedeemVerificationKey -> RedeemVerificationKey
fromCompactRedeemVerificationKey)
        ((CompactRedeemVerificationKey, Lovelace) -> (Address, Lovelace))
-> [(CompactRedeemVerificationKey, Lovelace)]
-> [(Address, Lovelace)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map CompactRedeemVerificationKey Lovelace
-> [(CompactRedeemVerificationKey, Lovelace)]
forall k a. Map k a -> [(k, a)]
M.toList (GenesisAvvmBalances -> Map CompactRedeemVerificationKey Lovelace
unGenesisAvvmBalances (GenesisAvvmBalances -> Map CompactRedeemVerificationKey Lovelace)
-> GenesisAvvmBalances -> Map CompactRedeemVerificationKey Lovelace
forall a b. (a -> b) -> a -> b
$ Config -> GenesisAvvmBalances
Genesis.configAvvmDistr Config
config)

    networkMagic :: NetworkMagic
    networkMagic :: NetworkMagic
networkMagic = AProtocolMagic () -> NetworkMagic
forall a. AProtocolMagic a -> NetworkMagic
makeNetworkMagic (Config -> AProtocolMagic ()
Genesis.configProtocolMagic Config
config)

    nonAvvmBalances :: [(Address, Lovelace)]
    nonAvvmBalances :: [(Address, Lovelace)]
nonAvvmBalances =
      Map Address Lovelace -> [(Address, Lovelace)]
forall k a. Map k a -> [(k, a)]
M.toList (Map Address Lovelace -> [(Address, Lovelace)])
-> Map Address Lovelace -> [(Address, Lovelace)]
forall a b. (a -> b) -> a -> b
$ GenesisNonAvvmBalances -> Map Address Lovelace
unGenesisNonAvvmBalances (GenesisNonAvvmBalances -> Map Address Lovelace)
-> GenesisNonAvvmBalances -> Map Address Lovelace
forall a b. (a -> b) -> a -> b
$ Config -> GenesisNonAvvmBalances
Genesis.configNonAvvmBalances Config
config