{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE BinaryLiterals #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_HADDOCK prune #-}
module Cardano.Address.Style.Shared
(
Shared
, getKey
, liftXPrv
, liftXPub
, sharedWalletId
, genMasterKeyFromXPrv
, genMasterKeyFromMnemonic
, deriveAccountPrivateKey
, deriveAddressPrivateKey
, deriveAddressPublicKey
, deriveDelegationPrivateKey
, deriveDelegationPublicKey
, hashKey
) where
import Prelude
import Cardano.Address.Derivation
( Depth (..)
, DerivationType (..)
, Index (..)
, XPrv
, XPub
, hashCredential
, hashWalletId
, xpubPublicKey
)
import Cardano.Address.Script
( Cosigner, KeyHash (..), KeyRole, Script )
import Cardano.Address.Script.Parser
( scriptToText )
import Cardano.Address.Style.Shelley
( Role (..)
, deriveAccountPrivateKeyShelley
, deriveAddressPrivateKeyShelley
, deriveAddressPublicKeyShelley
, genMasterKeyFromMnemonicShelley
)
import Cardano.Mnemonic
( SomeMnemonic )
import Control.DeepSeq
( NFData )
import Data.ByteArray
( ScrubbedBytes )
import Data.ByteString
( ByteString )
import Data.Coerce
( coerce )
import Data.Word
( Word32 )
import GHC.Generics
( Generic )
import qualified Cardano.Address.Derivation as Internal
import qualified Data.ByteString as BS
import qualified Data.Text.Encoding as T
newtype Shared (depth :: Depth) key = Shared
{ Shared depth key -> key
getKey :: key
}
deriving stock ((forall x. Shared depth key -> Rep (Shared depth key) x)
-> (forall x. Rep (Shared depth key) x -> Shared depth key)
-> Generic (Shared depth key)
forall x. Rep (Shared depth key) x -> Shared depth key
forall x. Shared depth key -> Rep (Shared depth key) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (depth :: Depth) key x.
Rep (Shared depth key) x -> Shared depth key
forall (depth :: Depth) key x.
Shared depth key -> Rep (Shared depth key) x
$cto :: forall (depth :: Depth) key x.
Rep (Shared depth key) x -> Shared depth key
$cfrom :: forall (depth :: Depth) key x.
Shared depth key -> Rep (Shared depth key) x
Generic, Int -> Shared depth key -> ShowS
[Shared depth key] -> ShowS
Shared depth key -> String
(Int -> Shared depth key -> ShowS)
-> (Shared depth key -> String)
-> ([Shared depth key] -> ShowS)
-> Show (Shared depth key)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (depth :: Depth) key.
Show key =>
Int -> Shared depth key -> ShowS
forall (depth :: Depth) key.
Show key =>
[Shared depth key] -> ShowS
forall (depth :: Depth) key. Show key => Shared depth key -> String
showList :: [Shared depth key] -> ShowS
$cshowList :: forall (depth :: Depth) key.
Show key =>
[Shared depth key] -> ShowS
show :: Shared depth key -> String
$cshow :: forall (depth :: Depth) key. Show key => Shared depth key -> String
showsPrec :: Int -> Shared depth key -> ShowS
$cshowsPrec :: forall (depth :: Depth) key.
Show key =>
Int -> Shared depth key -> ShowS
Show, Shared depth key -> Shared depth key -> Bool
(Shared depth key -> Shared depth key -> Bool)
-> (Shared depth key -> Shared depth key -> Bool)
-> Eq (Shared depth key)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (depth :: Depth) key.
Eq key =>
Shared depth key -> Shared depth key -> Bool
/= :: Shared depth key -> Shared depth key -> Bool
$c/= :: forall (depth :: Depth) key.
Eq key =>
Shared depth key -> Shared depth key -> Bool
== :: Shared depth key -> Shared depth key -> Bool
$c== :: forall (depth :: Depth) key.
Eq key =>
Shared depth key -> Shared depth key -> Bool
Eq)
deriving instance (Functor (Shared depth))
instance (NFData key) => NFData (Shared depth key)
instance Internal.GenMasterKey Shared where
type SecondFactor Shared = ScrubbedBytes
genMasterKeyFromXPrv :: XPrv -> Shared 'RootK XPrv
genMasterKeyFromXPrv = XPrv -> Shared 'RootK XPrv
forall (depth :: Depth). XPrv -> Shared depth XPrv
liftXPrv
genMasterKeyFromMnemonic :: SomeMnemonic -> SecondFactor Shared -> Shared 'RootK XPrv
genMasterKeyFromMnemonic SomeMnemonic
fstFactor SecondFactor Shared
sndFactor =
XPrv -> Shared 'RootK XPrv
forall (depth :: Depth) key. key -> Shared depth key
Shared (XPrv -> Shared 'RootK XPrv) -> XPrv -> Shared 'RootK XPrv
forall a b. (a -> b) -> a -> b
$ SomeMnemonic -> ScrubbedBytes -> XPrv
forall sndFactor.
ByteArrayAccess sndFactor =>
SomeMnemonic -> sndFactor -> XPrv
genMasterKeyFromMnemonicShelley SomeMnemonic
fstFactor ScrubbedBytes
SecondFactor Shared
sndFactor
instance Internal.HardDerivation Shared where
type AccountIndexDerivationType Shared = 'Hardened
type AddressIndexDerivationType Shared = 'Soft
type WithRole Shared = Role
deriveAccountPrivateKey :: Shared 'RootK XPrv
-> Index (AccountIndexDerivationType Shared) 'AccountK
-> Shared 'AccountK XPrv
deriveAccountPrivateKey (Shared XPrv
rootXPrv) Index (AccountIndexDerivationType Shared) 'AccountK
accIx =
XPrv -> Shared 'AccountK XPrv
forall (depth :: Depth) key. key -> Shared depth key
Shared (XPrv -> Shared 'AccountK XPrv) -> XPrv -> Shared 'AccountK XPrv
forall a b. (a -> b) -> a -> b
$ XPrv -> Index 'Hardened 'AccountK -> Word32 -> XPrv
forall (derivationType :: DerivationType) (depth :: Depth).
XPrv -> Index derivationType depth -> Word32 -> XPrv
deriveAccountPrivateKeyShelley XPrv
rootXPrv Index (AccountIndexDerivationType Shared) 'AccountK
Index 'Hardened 'AccountK
accIx Word32
purposeIndex
deriveAddressPrivateKey :: Shared 'AccountK XPrv
-> WithRole Shared
-> Index (AddressIndexDerivationType Shared) 'PaymentK
-> Shared 'PaymentK XPrv
deriveAddressPrivateKey (Shared XPrv
accXPrv) WithRole Shared
keyRole Index (AddressIndexDerivationType Shared) 'PaymentK
addrIx =
XPrv -> Shared 'PaymentK XPrv
forall (depth :: Depth) key. key -> Shared depth key
Shared (XPrv -> Shared 'PaymentK XPrv) -> XPrv -> Shared 'PaymentK XPrv
forall a b. (a -> b) -> a -> b
$ XPrv -> Role -> Index 'Soft 'PaymentK -> XPrv
forall (derivationType :: DerivationType) (depth :: Depth).
XPrv -> Role -> Index derivationType depth -> XPrv
deriveAddressPrivateKeyShelley XPrv
accXPrv WithRole Shared
Role
keyRole Index (AddressIndexDerivationType Shared) 'PaymentK
Index 'Soft 'PaymentK
addrIx
instance Internal.SoftDerivation Shared where
deriveAddressPublicKey :: Shared 'AccountK XPub
-> WithRole Shared
-> Index 'Soft 'PaymentK
-> Shared 'PaymentK XPub
deriveAddressPublicKey (Shared XPub
accXPub) WithRole Shared
keyRole Index 'Soft 'PaymentK
addrIx =
XPub -> Shared 'PaymentK XPub
forall (depth :: Depth) key. key -> Shared depth key
Shared (XPub -> Shared 'PaymentK XPub) -> XPub -> Shared 'PaymentK XPub
forall a b. (a -> b) -> a -> b
$ XPub -> Role -> Index 'Soft 'PaymentK -> XPub
forall (derivationType :: DerivationType) (depth :: Depth).
XPub -> Role -> Index derivationType depth -> XPub
deriveAddressPublicKeyShelley XPub
accXPub WithRole Shared
Role
keyRole Index 'Soft 'PaymentK
addrIx
genMasterKeyFromMnemonic
:: SomeMnemonic
-> ScrubbedBytes
-> Shared 'RootK XPrv
genMasterKeyFromMnemonic :: SomeMnemonic -> ScrubbedBytes -> Shared 'RootK XPrv
genMasterKeyFromMnemonic = SomeMnemonic -> ScrubbedBytes -> Shared 'RootK XPrv
forall (key :: Depth -> * -> *).
GenMasterKey key =>
SomeMnemonic -> SecondFactor key -> key 'RootK XPrv
Internal.genMasterKeyFromMnemonic
genMasterKeyFromXPrv :: XPrv -> Shared 'RootK XPrv
genMasterKeyFromXPrv :: XPrv -> Shared 'RootK XPrv
genMasterKeyFromXPrv = XPrv -> Shared 'RootK XPrv
forall (key :: Depth -> * -> *).
GenMasterKey key =>
XPrv -> key 'RootK XPrv
Internal.genMasterKeyFromXPrv
deriveAccountPrivateKey
:: Shared 'RootK XPrv
-> Index 'Hardened 'AccountK
-> Shared 'AccountK XPrv
deriveAccountPrivateKey :: Shared 'RootK XPrv
-> Index 'Hardened 'AccountK -> Shared 'AccountK XPrv
deriveAccountPrivateKey = Shared 'RootK XPrv
-> Index 'Hardened 'AccountK -> Shared 'AccountK XPrv
forall (key :: Depth -> * -> *).
HardDerivation key =>
key 'RootK XPrv
-> Index (AccountIndexDerivationType key) 'AccountK
-> key 'AccountK XPrv
Internal.deriveAccountPrivateKey
deriveAddressPrivateKey
:: Shared 'AccountK XPrv
-> Role
-> Index 'Soft 'PaymentK
-> Shared 'ScriptK XPrv
deriveAddressPrivateKey :: Shared 'AccountK XPrv
-> Role -> Index 'Soft 'PaymentK -> Shared 'ScriptK XPrv
deriveAddressPrivateKey = (Role -> Index 'Soft 'PaymentK -> Shared 'PaymentK XPrv)
-> Role -> Index 'Soft 'PaymentK -> Shared 'ScriptK XPrv
coerce ((Role -> Index 'Soft 'PaymentK -> Shared 'PaymentK XPrv)
-> Role -> Index 'Soft 'PaymentK -> Shared 'ScriptK XPrv)
-> (Shared 'AccountK XPrv
-> Role -> Index 'Soft 'PaymentK -> Shared 'PaymentK XPrv)
-> Shared 'AccountK XPrv
-> Role
-> Index 'Soft 'PaymentK
-> Shared 'ScriptK XPrv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Shared 'AccountK XPrv
-> Role -> Index 'Soft 'PaymentK -> Shared 'PaymentK XPrv
forall (key :: Depth -> * -> *).
HardDerivation key =>
key 'AccountK XPrv
-> WithRole key
-> Index (AddressIndexDerivationType key) 'PaymentK
-> key 'PaymentK XPrv
Internal.deriveAddressPrivateKey
deriveDelegationPrivateKey
:: Shared 'AccountK XPrv
-> Index 'Soft 'PaymentK
-> Shared 'ScriptK XPrv
deriveDelegationPrivateKey :: Shared 'AccountK XPrv
-> Index 'Soft 'PaymentK -> Shared 'ScriptK XPrv
deriveDelegationPrivateKey Shared 'AccountK XPrv
accPrv = Shared 'PaymentK XPrv -> Shared 'ScriptK XPrv
coerce (Shared 'PaymentK XPrv -> Shared 'ScriptK XPrv)
-> (Index 'Soft 'PaymentK -> Shared 'PaymentK XPrv)
-> Index 'Soft 'PaymentK
-> Shared 'ScriptK XPrv
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
Shared 'AccountK XPrv
-> WithRole Shared
-> Index (AddressIndexDerivationType Shared) 'PaymentK
-> Shared 'PaymentK XPrv
forall (key :: Depth -> * -> *).
HardDerivation key =>
key 'AccountK XPrv
-> WithRole key
-> Index (AddressIndexDerivationType key) 'PaymentK
-> key 'PaymentK XPrv
Internal.deriveAddressPrivateKey Shared 'AccountK XPrv
accPrv WithRole Shared
Role
Stake
deriveAddressPublicKey
:: Shared 'AccountK XPub
-> Role
-> Index 'Soft 'PaymentK
-> Shared 'ScriptK XPub
deriveAddressPublicKey :: Shared 'AccountK XPub
-> Role -> Index 'Soft 'PaymentK -> Shared 'ScriptK XPub
deriveAddressPublicKey = (Role -> Index 'Soft 'PaymentK -> Shared 'PaymentK XPub)
-> Role -> Index 'Soft 'PaymentK -> Shared 'ScriptK XPub
coerce ((Role -> Index 'Soft 'PaymentK -> Shared 'PaymentK XPub)
-> Role -> Index 'Soft 'PaymentK -> Shared 'ScriptK XPub)
-> (Shared 'AccountK XPub
-> Role -> Index 'Soft 'PaymentK -> Shared 'PaymentK XPub)
-> Shared 'AccountK XPub
-> Role
-> Index 'Soft 'PaymentK
-> Shared 'ScriptK XPub
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Shared 'AccountK XPub
-> Role -> Index 'Soft 'PaymentK -> Shared 'PaymentK XPub
forall (key :: Depth -> * -> *).
SoftDerivation key =>
key 'AccountK XPub
-> WithRole key -> Index 'Soft 'PaymentK -> key 'PaymentK XPub
Internal.deriveAddressPublicKey
deriveDelegationPublicKey
:: Shared 'AccountK XPub
-> Index 'Soft 'PaymentK
-> Shared 'ScriptK XPub
deriveDelegationPublicKey :: Shared 'AccountK XPub
-> Index 'Soft 'PaymentK -> Shared 'ScriptK XPub
deriveDelegationPublicKey Shared 'AccountK XPub
accPub = Shared 'PaymentK XPub -> Shared 'ScriptK XPub
coerce (Shared 'PaymentK XPub -> Shared 'ScriptK XPub)
-> (Index 'Soft 'PaymentK -> Shared 'PaymentK XPub)
-> Index 'Soft 'PaymentK
-> Shared 'ScriptK XPub
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
Shared 'AccountK XPub
-> WithRole Shared
-> Index 'Soft 'PaymentK
-> Shared 'PaymentK XPub
forall (key :: Depth -> * -> *).
SoftDerivation key =>
key 'AccountK XPub
-> WithRole key -> Index 'Soft 'PaymentK -> key 'PaymentK XPub
Internal.deriveAddressPublicKey Shared 'AccountK XPub
accPub WithRole Shared
Role
Stake
liftXPrv :: XPrv -> Shared depth XPrv
liftXPrv :: XPrv -> Shared depth XPrv
liftXPrv = XPrv -> Shared depth XPrv
forall (depth :: Depth) key. key -> Shared depth key
Shared
liftXPub :: XPub -> Shared depth XPub
liftXPub :: XPub -> Shared depth XPub
liftXPub = XPub -> Shared depth XPub
forall (depth :: Depth) key. key -> Shared depth key
Shared
sharedWalletId
:: ByteString
-> Script Cosigner
-> Maybe (Script Cosigner)
-> ByteString
sharedWalletId :: ByteString
-> Script Cosigner -> Maybe (Script Cosigner) -> ByteString
sharedWalletId ByteString
bytes Script Cosigner
spending Maybe (Script Cosigner)
stakingM =
if ByteString -> Int
BS.length ByteString
bytes Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 then
ByteString -> ByteString
hashWalletId (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$
ByteString
bytes ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<>
Script Cosigner -> ByteString
serializeScriptTemplate Script Cosigner
spending ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<>
ByteString
-> (Script Cosigner -> ByteString)
-> Maybe (Script Cosigner)
-> ByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ByteString
forall a. Monoid a => a
mempty Script Cosigner -> ByteString
serializeScriptTemplate Maybe (Script Cosigner)
stakingM
else
String -> ByteString
forall a. HasCallStack => String -> a
error String
"Extended account public key is expected to have 64 bytes."
where
serializeScriptTemplate :: Script Cosigner -> ByteString
serializeScriptTemplate = Text -> ByteString
T.encodeUtf8 (Text -> ByteString)
-> (Script Cosigner -> Text) -> Script Cosigner -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Script Cosigner -> Text
forall a. Show a => Script a -> Text
scriptToText
hashKey :: KeyRole -> Shared key XPub -> KeyHash
hashKey :: KeyRole -> Shared key XPub -> KeyHash
hashKey KeyRole
cred = KeyRole -> ByteString -> KeyHash
KeyHash KeyRole
cred (ByteString -> KeyHash)
-> (Shared key XPub -> ByteString) -> Shared key XPub -> KeyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
hashCredential (ByteString -> ByteString)
-> (Shared key XPub -> ByteString) -> Shared key XPub -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XPub -> ByteString
xpubPublicKey (XPub -> ByteString)
-> (Shared key XPub -> XPub) -> Shared key XPub -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Shared key XPub -> XPub
forall (depth :: Depth) key. Shared depth key -> key
getKey
purposeIndex :: Word32
purposeIndex :: Word32
purposeIndex = Word32
0x8000073e