{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

-- | Tools for building unique Key (and related types) by just supplying an Int
--   Each Int returns a different Key (or related type)
--   Useful when writing unit tests
module Test.Cardano.Ledger.Generic.Indexed where

import Cardano.Crypto.DSIGN.Class (SignKeyDSIGN)
import Cardano.Ledger.Core
import Cardano.Ledger.Credential (Credential (..), StakeReference (..))
import Cardano.Ledger.Keys (DSIGN, VKey, WitVKey (..))
import Test.Cardano.Ledger.Core.KeyPair (KeyPair (..), mkWitnessVKey)
import Test.Cardano.Ledger.Generic.Proof (Proof (..))
import Test.Cardano.Ledger.Shelley.Utils (RawSeed (..), mkKeyPair)

-- =======================================================
-- Keys and KeyHashes

-- | A signing key
newtype SKey (kr :: KeyRole) = SKey (SignKeyDSIGN DSIGN)

-- By changing the parameter 'n', we get a different keyPair
theKeyPair :: Int -> KeyPair kr
theKeyPair :: forall (kr :: KeyRole). Int -> KeyPair kr
theKeyPair Int
n = VKey kr -> SignKeyDSIGN DSIGN -> KeyPair kr
forall (kd :: KeyRole). VKey kd -> SignKeyDSIGN DSIGN -> KeyPair kd
KeyPair VKey kr
a SignKeyDSIGN DSIGN
b
  where
    (SignKeyDSIGN DSIGN
b, VKey kr
a) = RawSeed -> (SignKeyDSIGN DSIGN, VKey kr)
forall (kd :: KeyRole). RawSeed -> (SignKeyDSIGN DSIGN, VKey kd)
mkKeyPair (Word64 -> Word64 -> Word64 -> Word64 -> Word64 -> RawSeed
RawSeed Word64
0 Word64
0 Word64
0 Word64
0 (Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n))

theVKey :: Int -> VKey kr
theVKey :: forall (kr :: KeyRole). Int -> VKey kr
theVKey Int
n = KeyPair kr -> VKey kr
forall (kd :: KeyRole). KeyPair kd -> VKey kd
vKey (Int -> KeyPair kr
forall (kr :: KeyRole). Int -> KeyPair kr
theKeyPair Int
n)

theSKey :: forall kr. Int -> SKey kr
theSKey :: forall (kr :: KeyRole). Int -> SKey kr
theSKey Int
n = SignKeyDSIGN DSIGN -> SKey kr
forall (kr :: KeyRole). SignKeyDSIGN DSIGN -> SKey kr
SKey (KeyPair Any -> SignKeyDSIGN DSIGN
forall (kd :: KeyRole). KeyPair kd -> SignKeyDSIGN DSIGN
sKey (Int -> KeyPair Any
forall (kr :: KeyRole). Int -> KeyPair kr
theKeyPair Int
n))

theKeyHash :: Int -> KeyHash kr
theKeyHash :: forall (kr :: KeyRole). Int -> KeyHash kr
theKeyHash Int
n = VKey kr -> KeyHash kr
forall (kd :: KeyRole). VKey kd -> KeyHash kd
hashKey (Int -> VKey kr
forall (kr :: KeyRole). Int -> VKey kr
theVKey Int
n)

theWitVKey ::
  Int ->
  SafeHash EraIndependentTxBody ->
  WitVKey 'Witness
theWitVKey :: Int -> SafeHash EraIndependentTxBody -> WitVKey 'Witness
theWitVKey Int
n SafeHash EraIndependentTxBody
hash = SafeHash EraIndependentTxBody -> KeyPair Any -> WitVKey 'Witness
forall (kr :: KeyRole).
SafeHash EraIndependentTxBody -> KeyPair kr -> WitVKey 'Witness
mkWitnessVKey SafeHash EraIndependentTxBody
hash (Int -> KeyPair Any
forall (kr :: KeyRole). Int -> KeyPair kr
theKeyPair Int
n)

theKeyHashObj :: Int -> Credential kr
theKeyHashObj :: forall (kr :: KeyRole). Int -> Credential kr
theKeyHashObj Int
n = KeyHash kr -> Credential kr
forall (kr :: KeyRole). KeyHash kr -> Credential kr
KeyHashObj (KeyHash kr -> Credential kr)
-> (KeyPair kr -> KeyHash kr) -> KeyPair kr -> Credential kr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VKey kr -> KeyHash kr
forall (kd :: KeyRole). VKey kd -> KeyHash kd
hashKey (VKey kr -> KeyHash kr)
-> (KeyPair kr -> VKey kr) -> KeyPair kr -> KeyHash kr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyPair kr -> VKey kr
forall (kd :: KeyRole). KeyPair kd -> VKey kd
vKey (KeyPair kr -> Credential kr) -> KeyPair kr -> Credential kr
forall a b. (a -> b) -> a -> b
$ Int -> KeyPair kr
forall (kr :: KeyRole). Int -> KeyPair kr
theKeyPair Int
n

aScriptHashObj ::
  forall era kr. EraScript era => Proof era -> Script era -> Credential kr
aScriptHashObj :: forall era (kr :: KeyRole).
EraScript era =>
Proof era -> Script era -> Credential kr
aScriptHashObj Proof era
_wit = ScriptHash -> Credential kr
forall (kr :: KeyRole). ScriptHash -> Credential kr
ScriptHashObj (ScriptHash -> Credential kr)
-> (Script era -> ScriptHash) -> Script era -> Credential kr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall era. EraScript era => Script era -> ScriptHash
hashScript @era

theStakeReference :: Int -> StakeReference
theStakeReference :: Int -> StakeReference
theStakeReference Int
n = (StakeCredential -> StakeReference
StakeRefBase (StakeCredential -> StakeReference)
-> (VKey 'Staking -> StakeCredential)
-> VKey 'Staking
-> StakeReference
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyHash 'Staking -> StakeCredential
forall (kr :: KeyRole). KeyHash kr -> Credential kr
KeyHashObj (KeyHash 'Staking -> StakeCredential)
-> (VKey 'Staking -> KeyHash 'Staking)
-> VKey 'Staking
-> StakeCredential
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VKey 'Staking -> KeyHash 'Staking
forall (kd :: KeyRole). VKey kd -> KeyHash kd
hashKey) (Int -> VKey 'Staking
forall (kr :: KeyRole). Int -> VKey kr
theVKey Int
n)