{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Cardano.Wallet.Primitive.AddressDerivation
(
Depth (..)
, Index (..)
, Role (..)
, roleVal
, utxoExternal
, utxoInternal
, mutableAccount
, zeroAccount
, stakeDerivationPath
, DerivationType (..)
, HardDerivation (..)
, SoftDerivation (..)
, DerivationPrefix (..)
, DerivationIndex (..)
, liftIndex
, hashVerificationKey
, RewardAccount (..)
, ToRewardAccount(..)
, deriveRewardAccount
, hex
, fromHex
, NetworkDiscriminant (..)
, NetworkDiscriminantVal
, networkDiscriminantVal
, PaymentAddress(..)
, DelegationAddress(..)
, BoundedAddressLength (..)
, WalletKey(..)
, PersistPrivateKey(..)
, PersistPublicKey(..)
, MkKeyFingerprint(..)
, ErrMkKeyFingerprint(..)
, KeyFingerprint(..)
) where
import Prelude
import Cardano.Address.Derivation
( XPrv, XPub, xpubPublicKey )
import Cardano.Address.Script
( KeyHash (..), KeyRole )
import Cardano.Mnemonic
( SomeMnemonic )
import Cardano.Wallet.Primitive.Passphrase.Types
( Passphrase (..), PassphraseHash (..), PassphraseScheme )
import Cardano.Wallet.Primitive.Types.Address
( Address (..) )
import Cardano.Wallet.Primitive.Types.RewardAccount
( RewardAccount (..) )
import Control.Applicative
( (<|>) )
import Control.DeepSeq
( NFData )
import Control.Monad
( (>=>) )
import Crypto.Hash
( Digest, HashAlgorithm )
import Crypto.Hash.Utils
( blake2b224 )
import Data.ByteArray
( ByteArray, ByteArrayAccess )
import Data.ByteArray.Encoding
( Base (..), convertFromBase, convertToBase )
import Data.ByteString
( ByteString )
import Data.Kind
( Type )
import Data.List.NonEmpty
( NonEmpty (..) )
import Data.Maybe
( fromMaybe )
import Data.Proxy
( Proxy (..) )
import Data.Scientific
( Scientific, toBoundedInteger )
import Data.String
( fromString )
import Data.Text
( Text )
import Data.Text.Class
( CaseStyle (..)
, FromText (..)
, TextDecodingError (..)
, ToText (..)
, fromTextToBoundedEnum
, toTextFromBoundedEnum
)
import Data.Type.Equality
( (:~:) (..), testEquality )
import Data.Word
( Word32 )
import Fmt
( Buildable (..) )
import GHC.Generics
( Generic )
import GHC.TypeLits
( KnownNat, Nat, Symbol, natVal )
import Quiet
( Quiet (..) )
import Safe
( readMay, toEnumMay )
import Type.Reflection
( Typeable, typeRep )
import qualified Data.Text as T
data Depth
= RootK
| PurposeK
| CoinTypeK
| AccountK
| RoleK
| AddressK
| ScriptK
| PolicyK
data Role
= UtxoExternal
| UtxoInternal
| MutableAccount
deriving ((forall x. Role -> Rep Role x)
-> (forall x. Rep Role x -> Role) -> Generic Role
forall x. Rep Role x -> Role
forall x. Role -> Rep Role x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Role x -> Role
$cfrom :: forall x. Role -> Rep Role x
Generic, Typeable, Int -> Role -> ShowS
[Role] -> ShowS
Role -> String
(Int -> Role -> ShowS)
-> (Role -> String) -> ([Role] -> ShowS) -> Show Role
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Role] -> ShowS
$cshowList :: [Role] -> ShowS
show :: Role -> String
$cshow :: Role -> String
showsPrec :: Int -> Role -> ShowS
$cshowsPrec :: Int -> Role -> ShowS
Show, Role -> Role -> Bool
(Role -> Role -> Bool) -> (Role -> Role -> Bool) -> Eq Role
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Role -> Role -> Bool
$c/= :: Role -> Role -> Bool
== :: Role -> Role -> Bool
$c== :: Role -> Role -> Bool
Eq, Eq Role
Eq Role
-> (Role -> Role -> Ordering)
-> (Role -> Role -> Bool)
-> (Role -> Role -> Bool)
-> (Role -> Role -> Bool)
-> (Role -> Role -> Bool)
-> (Role -> Role -> Role)
-> (Role -> Role -> Role)
-> Ord Role
Role -> Role -> Bool
Role -> Role -> Ordering
Role -> Role -> Role
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 :: Role -> Role -> Role
$cmin :: Role -> Role -> Role
max :: Role -> Role -> Role
$cmax :: Role -> Role -> Role
>= :: Role -> Role -> Bool
$c>= :: Role -> Role -> Bool
> :: Role -> Role -> Bool
$c> :: Role -> Role -> Bool
<= :: Role -> Role -> Bool
$c<= :: Role -> Role -> Bool
< :: Role -> Role -> Bool
$c< :: Role -> Role -> Bool
compare :: Role -> Role -> Ordering
$ccompare :: Role -> Role -> Ordering
$cp1Ord :: Eq Role
Ord, Role
Role -> Role -> Bounded Role
forall a. a -> a -> Bounded a
maxBound :: Role
$cmaxBound :: Role
minBound :: Role
$cminBound :: Role
Bounded)
instance NFData Role
instance Enum Role where
toEnum :: Int -> Role
toEnum = \case
Int
0 -> Role
UtxoExternal
Int
1 -> Role
UtxoInternal
Int
2 -> Role
MutableAccount
Int
_ -> String -> Role
forall a. HasCallStack => String -> a
error String
"Role.toEnum: bad argument"
fromEnum :: Role -> Int
fromEnum = \case
Role
UtxoExternal -> Int
0
Role
UtxoInternal -> Int
1
Role
MutableAccount -> Int
2
instance ToText Role where
toText :: Role -> Text
toText = CaseStyle -> Role -> Text
forall a. (Bounded a, Enum a, Show a) => CaseStyle -> a -> Text
toTextFromBoundedEnum CaseStyle
SnakeLowerCase
instance FromText Role where
fromText :: Text -> Either TextDecodingError Role
fromText = CaseStyle -> Text -> Either TextDecodingError Role
forall a.
(Bounded a, Enum a, Show a) =>
CaseStyle -> Text -> Either TextDecodingError a
fromTextToBoundedEnum CaseStyle
SnakeLowerCase
roleVal :: forall (c :: Role). Typeable c => Role
roleVal :: Role
roleVal = Role -> Maybe Role -> Role
forall a. a -> Maybe a -> a
fromMaybe (String -> Role
forall a. HasCallStack => String -> a
error (String -> Role) -> String -> Role
forall a b. (a -> b) -> a -> b
$ String
"role: unmatched type" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TypeRep c -> String
forall a. Show a => a -> String
show (Typeable c => TypeRep c
forall k (a :: k). Typeable a => TypeRep a
typeRep @c))
(Maybe Role
tryUtxoExternal Maybe Role -> Maybe Role -> Maybe Role
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Role
tryUtxoInternal Maybe Role -> Maybe Role -> Maybe Role
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Role
tryMutableAccount)
where
tryUtxoExternal :: Maybe Role
tryUtxoExternal =
case TypeRep c -> TypeRep 'UtxoExternal -> Maybe (c :~: 'UtxoExternal)
forall k (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (Typeable c => TypeRep c
forall k (a :: k). Typeable a => TypeRep a
typeRep @c) (Typeable 'UtxoExternal => TypeRep 'UtxoExternal
forall k (a :: k). Typeable a => TypeRep a
typeRep @'UtxoExternal) of
Just c :~: 'UtxoExternal
Refl -> Role -> Maybe Role
forall a. a -> Maybe a
Just Role
UtxoExternal
Maybe (c :~: 'UtxoExternal)
Nothing -> Maybe Role
forall a. Maybe a
Nothing
tryUtxoInternal :: Maybe Role
tryUtxoInternal =
case TypeRep c -> TypeRep 'UtxoInternal -> Maybe (c :~: 'UtxoInternal)
forall k (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (Typeable c => TypeRep c
forall k (a :: k). Typeable a => TypeRep a
typeRep @c) (Typeable 'UtxoInternal => TypeRep 'UtxoInternal
forall k (a :: k). Typeable a => TypeRep a
typeRep @'UtxoInternal) of
Just c :~: 'UtxoInternal
Refl -> Role -> Maybe Role
forall a. a -> Maybe a
Just Role
UtxoInternal
Maybe (c :~: 'UtxoInternal)
Nothing -> Maybe Role
forall a. Maybe a
Nothing
tryMutableAccount :: Maybe Role
tryMutableAccount =
case TypeRep c
-> TypeRep 'MutableAccount -> Maybe (c :~: 'MutableAccount)
forall k (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (Typeable c => TypeRep c
forall k (a :: k). Typeable a => TypeRep a
typeRep @c) (Typeable 'MutableAccount => TypeRep 'MutableAccount
forall k (a :: k). Typeable a => TypeRep a
typeRep @'MutableAccount) of
Just c :~: 'MutableAccount
Refl -> Role -> Maybe Role
forall a. a -> Maybe a
Just Role
MutableAccount
Maybe (c :~: 'MutableAccount)
Nothing -> Maybe Role
forall a. Maybe a
Nothing
utxoExternal :: Index 'Soft 'RoleK
utxoExternal :: Index 'Soft 'RoleK
utxoExternal = Int -> Index 'Soft 'RoleK
forall a. Enum a => Int -> a
toEnum (Int -> Index 'Soft 'RoleK) -> Int -> Index 'Soft 'RoleK
forall a b. (a -> b) -> a -> b
$ Role -> Int
forall a. Enum a => a -> Int
fromEnum Role
UtxoExternal
utxoInternal :: Index 'Soft 'RoleK
utxoInternal :: Index 'Soft 'RoleK
utxoInternal = Int -> Index 'Soft 'RoleK
forall a. Enum a => Int -> a
toEnum (Int -> Index 'Soft 'RoleK) -> Int -> Index 'Soft 'RoleK
forall a b. (a -> b) -> a -> b
$ Role -> Int
forall a. Enum a => a -> Int
fromEnum Role
UtxoInternal
mutableAccount :: Index 'Soft 'RoleK
mutableAccount :: Index 'Soft 'RoleK
mutableAccount = Int -> Index 'Soft 'RoleK
forall a. Enum a => Int -> a
toEnum (Int -> Index 'Soft 'RoleK) -> Int -> Index 'Soft 'RoleK
forall a b. (a -> b) -> a -> b
$ Role -> Int
forall a. Enum a => a -> Int
fromEnum Role
MutableAccount
zeroAccount :: Index 'Soft 'AddressK
zeroAccount :: Index 'Soft 'AddressK
zeroAccount = Index 'Soft 'AddressK
forall a. Bounded a => a
minBound
stakeDerivationPath :: DerivationPrefix -> NonEmpty DerivationIndex
stakeDerivationPath :: DerivationPrefix -> NonEmpty DerivationIndex
stakeDerivationPath (DerivationPrefix (Index 'Hardened 'PurposeK
purpose, Index 'Hardened 'CoinTypeK
coin, Index 'Hardened 'AccountK
acc)) =
(Index 'Hardened 'PurposeK -> DerivationIndex
forall (t :: DerivationType) (l :: Depth).
Index t l -> DerivationIndex
fromIndex Index 'Hardened 'PurposeK
purpose) DerivationIndex -> [DerivationIndex] -> NonEmpty DerivationIndex
forall a. a -> [a] -> NonEmpty a
:| [
Index 'Hardened 'CoinTypeK -> DerivationIndex
forall (t :: DerivationType) (l :: Depth).
Index t l -> DerivationIndex
fromIndex Index 'Hardened 'CoinTypeK
coin
, Index 'Hardened 'AccountK -> DerivationIndex
forall (t :: DerivationType) (l :: Depth).
Index t l -> DerivationIndex
fromIndex Index 'Hardened 'AccountK
acc
, Index 'Soft 'RoleK -> DerivationIndex
forall (t :: DerivationType) (l :: Depth).
Index t l -> DerivationIndex
fromIndex Index 'Soft 'RoleK
mutableAccount
, Index 'Soft 'AddressK -> DerivationIndex
forall (t :: DerivationType) (l :: Depth).
Index t l -> DerivationIndex
fromIndex Index 'Soft 'AddressK
zeroAccount]
where
fromIndex :: Index t l -> DerivationIndex
fromIndex :: Index t l -> DerivationIndex
fromIndex = Word32 -> DerivationIndex
DerivationIndex (Word32 -> DerivationIndex)
-> (Index t l -> Word32) -> Index t l -> DerivationIndex
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index t l -> Word32
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Word32
getIndex
newtype DerivationIndex
= DerivationIndex { DerivationIndex -> Word32
getDerivationIndex :: Word32 }
deriving (DerivationIndex -> DerivationIndex -> Bool
(DerivationIndex -> DerivationIndex -> Bool)
-> (DerivationIndex -> DerivationIndex -> Bool)
-> Eq DerivationIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DerivationIndex -> DerivationIndex -> Bool
$c/= :: DerivationIndex -> DerivationIndex -> Bool
== :: DerivationIndex -> DerivationIndex -> Bool
$c== :: DerivationIndex -> DerivationIndex -> Bool
Eq, Eq DerivationIndex
Eq DerivationIndex
-> (DerivationIndex -> DerivationIndex -> Ordering)
-> (DerivationIndex -> DerivationIndex -> Bool)
-> (DerivationIndex -> DerivationIndex -> Bool)
-> (DerivationIndex -> DerivationIndex -> Bool)
-> (DerivationIndex -> DerivationIndex -> Bool)
-> (DerivationIndex -> DerivationIndex -> DerivationIndex)
-> (DerivationIndex -> DerivationIndex -> DerivationIndex)
-> Ord DerivationIndex
DerivationIndex -> DerivationIndex -> Bool
DerivationIndex -> DerivationIndex -> Ordering
DerivationIndex -> DerivationIndex -> DerivationIndex
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 :: DerivationIndex -> DerivationIndex -> DerivationIndex
$cmin :: DerivationIndex -> DerivationIndex -> DerivationIndex
max :: DerivationIndex -> DerivationIndex -> DerivationIndex
$cmax :: DerivationIndex -> DerivationIndex -> DerivationIndex
>= :: DerivationIndex -> DerivationIndex -> Bool
$c>= :: DerivationIndex -> DerivationIndex -> Bool
> :: DerivationIndex -> DerivationIndex -> Bool
$c> :: DerivationIndex -> DerivationIndex -> Bool
<= :: DerivationIndex -> DerivationIndex -> Bool
$c<= :: DerivationIndex -> DerivationIndex -> Bool
< :: DerivationIndex -> DerivationIndex -> Bool
$c< :: DerivationIndex -> DerivationIndex -> Bool
compare :: DerivationIndex -> DerivationIndex -> Ordering
$ccompare :: DerivationIndex -> DerivationIndex -> Ordering
$cp1Ord :: Eq DerivationIndex
Ord, (forall x. DerivationIndex -> Rep DerivationIndex x)
-> (forall x. Rep DerivationIndex x -> DerivationIndex)
-> Generic DerivationIndex
forall x. Rep DerivationIndex x -> DerivationIndex
forall x. DerivationIndex -> Rep DerivationIndex x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DerivationIndex x -> DerivationIndex
$cfrom :: forall x. DerivationIndex -> Rep DerivationIndex x
Generic)
deriving Int -> DerivationIndex -> ShowS
[DerivationIndex] -> ShowS
DerivationIndex -> String
(Int -> DerivationIndex -> ShowS)
-> (DerivationIndex -> String)
-> ([DerivationIndex] -> ShowS)
-> Show DerivationIndex
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DerivationIndex] -> ShowS
$cshowList :: [DerivationIndex] -> ShowS
show :: DerivationIndex -> String
$cshow :: DerivationIndex -> String
showsPrec :: Int -> DerivationIndex -> ShowS
$cshowsPrec :: Int -> DerivationIndex -> ShowS
Show via (Quiet DerivationIndex)
instance NFData DerivationIndex
instance ToText DerivationIndex where
toText :: DerivationIndex -> Text
toText (DerivationIndex Word32
ix)
| Word32
ix Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word32
firstHardened = String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Word32 -> String
forall a. Show a => a -> String
show (Word32
ix Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
firstHardened) String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"H"
| Bool
otherwise = String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Word32 -> String
forall a. Show a => a -> String
show Word32
ix
where
firstHardened :: Word32
firstHardened = Index 'Hardened Any -> Word32
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Word32
getIndex @'Hardened Index 'Hardened Any
forall a. Bounded a => a
minBound
instance FromText DerivationIndex where
fromText :: Text -> Either TextDecodingError DerivationIndex
fromText Text
source =
if Text
"H" Text -> Text -> Bool
`T.isSuffixOf` Text
source then do
DerivationIndex Word32
ix <- Text -> Either TextDecodingError Scientific
castNumber (Text -> Text
T.init Text
source) Either TextDecodingError Scientific
-> (Scientific -> Either TextDecodingError DerivationIndex)
-> Either TextDecodingError DerivationIndex
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Scientific -> Either TextDecodingError DerivationIndex
parseAsScientific
DerivationIndex -> Either TextDecodingError DerivationIndex
forall (f :: * -> *) a. Applicative f => a -> f a
pure (DerivationIndex -> Either TextDecodingError DerivationIndex)
-> DerivationIndex -> Either TextDecodingError DerivationIndex
forall a b. (a -> b) -> a -> b
$ Word32 -> DerivationIndex
DerivationIndex (Word32 -> DerivationIndex) -> Word32 -> DerivationIndex
forall a b. (a -> b) -> a -> b
$ Word32
ix Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
firstHardened
else
Text -> Either TextDecodingError Scientific
castNumber Text
source Either TextDecodingError Scientific
-> (Scientific -> Either TextDecodingError DerivationIndex)
-> Either TextDecodingError DerivationIndex
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Scientific -> Either TextDecodingError DerivationIndex
parseAsScientific
where
firstHardened :: Word32
firstHardened = Index 'Hardened Any -> Word32
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Word32
getIndex @'Hardened Index 'Hardened Any
forall a. Bounded a => a
minBound
errMalformed :: TextDecodingError
errMalformed = String -> TextDecodingError
TextDecodingError (String -> TextDecodingError) -> String -> TextDecodingError
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
[ String
"A derivation index must be a natural number between"
, Word32 -> String
forall a. Show a => a -> String
show (Index 'Soft Any -> Word32
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Word32
getIndex @'Soft Index 'Soft Any
forall a. Bounded a => a
minBound)
, String
"and"
, Word32 -> String
forall a. Show a => a -> String
show (Index 'Soft Any -> Word32
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Word32
getIndex @'Soft Index 'Soft Any
forall a. Bounded a => a
maxBound)
, String
"with an optional 'H' suffix (e.g. '1815H' or '44')."
, String
"Indexes without suffixes are called 'Soft'"
, String
"Indexes with suffixes are called 'Hardened'."
]
parseAsScientific :: Scientific -> Either TextDecodingError DerivationIndex
parseAsScientific :: Scientific -> Either TextDecodingError DerivationIndex
parseAsScientific Scientific
x =
case Scientific -> Maybe Word32
forall i. (Integral i, Bounded i) => Scientific -> Maybe i
toBoundedInteger Scientific
x of
Just Word32
ix | Word32
ix Word32 -> Word32 -> Bool
forall a. Ord a => a -> a -> Bool
< Word32
firstHardened ->
DerivationIndex -> Either TextDecodingError DerivationIndex
forall (f :: * -> *) a. Applicative f => a -> f a
pure (DerivationIndex -> Either TextDecodingError DerivationIndex)
-> DerivationIndex -> Either TextDecodingError DerivationIndex
forall a b. (a -> b) -> a -> b
$ Word32 -> DerivationIndex
DerivationIndex Word32
ix
Maybe Word32
_ ->
TextDecodingError -> Either TextDecodingError DerivationIndex
forall a b. a -> Either a b
Left TextDecodingError
errMalformed
castNumber :: Text -> Either TextDecodingError Scientific
castNumber :: Text -> Either TextDecodingError Scientific
castNumber Text
txt =
case String -> Maybe Scientific
forall a. Read a => String -> Maybe a
readMay (Text -> String
T.unpack Text
txt) of
Maybe Scientific
Nothing ->
TextDecodingError -> Either TextDecodingError Scientific
forall a b. a -> Either a b
Left TextDecodingError
errMalformed
Just Scientific
s ->
Scientific -> Either TextDecodingError Scientific
forall (f :: * -> *) a. Applicative f => a -> f a
pure Scientific
s
newtype Index (derivationType :: DerivationType) (level :: Depth) = Index
{ Index derivationType level -> Word32
getIndex :: Word32 }
deriving stock ((forall x.
Index derivationType level -> Rep (Index derivationType level) x)
-> (forall x.
Rep (Index derivationType level) x -> Index derivationType level)
-> Generic (Index derivationType level)
forall x.
Rep (Index derivationType level) x -> Index derivationType level
forall x.
Index derivationType level -> Rep (Index derivationType level) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (derivationType :: DerivationType) (level :: Depth) x.
Rep (Index derivationType level) x -> Index derivationType level
forall (derivationType :: DerivationType) (level :: Depth) x.
Index derivationType level -> Rep (Index derivationType level) x
$cto :: forall (derivationType :: DerivationType) (level :: Depth) x.
Rep (Index derivationType level) x -> Index derivationType level
$cfrom :: forall (derivationType :: DerivationType) (level :: Depth) x.
Index derivationType level -> Rep (Index derivationType level) x
Generic, Int -> Index derivationType level -> ShowS
[Index derivationType level] -> ShowS
Index derivationType level -> String
(Int -> Index derivationType level -> ShowS)
-> (Index derivationType level -> String)
-> ([Index derivationType level] -> ShowS)
-> Show (Index derivationType level)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (derivationType :: DerivationType) (level :: Depth).
Int -> Index derivationType level -> ShowS
forall (derivationType :: DerivationType) (level :: Depth).
[Index derivationType level] -> ShowS
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> String
showList :: [Index derivationType level] -> ShowS
$cshowList :: forall (derivationType :: DerivationType) (level :: Depth).
[Index derivationType level] -> ShowS
show :: Index derivationType level -> String
$cshow :: forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> String
showsPrec :: Int -> Index derivationType level -> ShowS
$cshowsPrec :: forall (derivationType :: DerivationType) (level :: Depth).
Int -> Index derivationType level -> ShowS
Show, Index derivationType level -> Index derivationType level -> Bool
(Index derivationType level -> Index derivationType level -> Bool)
-> (Index derivationType level
-> Index derivationType level -> Bool)
-> Eq (Index derivationType level)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Index derivationType level -> Bool
/= :: Index derivationType level -> Index derivationType level -> Bool
$c/= :: forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Index derivationType level -> Bool
== :: Index derivationType level -> Index derivationType level -> Bool
$c== :: forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Index derivationType level -> Bool
Eq, Eq (Index derivationType level)
Eq (Index derivationType level)
-> (Index derivationType level
-> Index derivationType level -> Ordering)
-> (Index derivationType level
-> Index derivationType level -> Bool)
-> (Index derivationType level
-> Index derivationType level -> Bool)
-> (Index derivationType level
-> Index derivationType level -> Bool)
-> (Index derivationType level
-> Index derivationType level -> Bool)
-> (Index derivationType level
-> Index derivationType level -> Index derivationType level)
-> (Index derivationType level
-> Index derivationType level -> Index derivationType level)
-> Ord (Index derivationType level)
Index derivationType level -> Index derivationType level -> Bool
Index derivationType level
-> Index derivationType level -> Ordering
Index derivationType level
-> Index derivationType level -> Index derivationType level
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
forall (derivationType :: DerivationType) (level :: Depth).
Eq (Index derivationType level)
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Index derivationType level -> Bool
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level
-> Index derivationType level -> Ordering
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level
-> Index derivationType level -> Index derivationType level
min :: Index derivationType level
-> Index derivationType level -> Index derivationType level
$cmin :: forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level
-> Index derivationType level -> Index derivationType level
max :: Index derivationType level
-> Index derivationType level -> Index derivationType level
$cmax :: forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level
-> Index derivationType level -> Index derivationType level
>= :: Index derivationType level -> Index derivationType level -> Bool
$c>= :: forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Index derivationType level -> Bool
> :: Index derivationType level -> Index derivationType level -> Bool
$c> :: forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Index derivationType level -> Bool
<= :: Index derivationType level -> Index derivationType level -> Bool
$c<= :: forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Index derivationType level -> Bool
< :: Index derivationType level -> Index derivationType level -> Bool
$c< :: forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Index derivationType level -> Bool
compare :: Index derivationType level
-> Index derivationType level -> Ordering
$ccompare :: forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level
-> Index derivationType level -> Ordering
$cp1Ord :: forall (derivationType :: DerivationType) (level :: Depth).
Eq (Index derivationType level)
Ord)
instance NFData (Index derivationType level)
instance Bounded (Index 'Hardened level) where
minBound :: Index 'Hardened level
minBound = Word32 -> Index 'Hardened level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index Word32
0x80000000
maxBound :: Index 'Hardened level
maxBound = Word32 -> Index 'Hardened level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index Word32
forall a. Bounded a => a
maxBound
instance Bounded (Index 'Soft level) where
minBound :: Index 'Soft level
minBound = Word32 -> Index 'Soft level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index Word32
forall a. Bounded a => a
minBound
maxBound :: Index 'Soft level
maxBound = let (Index Word32
ix) = Bounded (Index 'Hardened Any) => Index 'Hardened Any
forall a. Bounded a => a
minBound @(Index 'Hardened _) in Word32 -> Index 'Soft level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index (Word32
ix Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
- Word32
1)
instance Bounded (Index 'WholeDomain level) where
minBound :: Index 'WholeDomain level
minBound = Word32 -> Index 'WholeDomain level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index Word32
forall a. Bounded a => a
minBound
maxBound :: Index 'WholeDomain level
maxBound = Word32 -> Index 'WholeDomain level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index Word32
forall a. Bounded a => a
maxBound
instance Enum (Index 'Hardened level) where
fromEnum :: Index 'Hardened level -> Int
fromEnum (Index Word32
ix) = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
ix
toEnum :: Int -> Index 'Hardened level
toEnum Int
ix
| Word32 -> Index 'Hardened Any
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ix) Index 'Hardened Any -> Index 'Hardened Any -> Bool
forall a. Ord a => a -> a -> Bool
< Bounded (Index 'Hardened Any) => Index 'Hardened Any
forall a. Bounded a => a
minBound @(Index 'Hardened _) =
String -> Index 'Hardened level
forall a. HasCallStack => String -> a
error String
"Index@Hardened.toEnum: bad argument"
| Bool
otherwise =
Word32 -> Index 'Hardened level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ix)
instance Enum (Index 'Soft level) where
fromEnum :: Index 'Soft level -> Int
fromEnum (Index Word32
ix) = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
ix
toEnum :: Int -> Index 'Soft level
toEnum Int
ix
| Word32 -> Index 'Soft Any
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ix) Index 'Soft Any -> Index 'Soft Any -> Bool
forall a. Ord a => a -> a -> Bool
> Bounded (Index 'Soft Any) => Index 'Soft Any
forall a. Bounded a => a
maxBound @(Index 'Soft _) =
String -> Index 'Soft level
forall a. HasCallStack => String -> a
error String
"Index@Soft.toEnum: bad argument"
| Bool
otherwise =
Word32 -> Index 'Soft level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ix)
instance Enum (Index 'WholeDomain level) where
fromEnum :: Index 'WholeDomain level -> Int
fromEnum (Index Word32
ix) = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
ix
toEnum :: Int -> Index 'WholeDomain level
toEnum Int
ix
| Word32 -> Index 'WholeDomain Any
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ix) Index 'WholeDomain Any -> Index 'WholeDomain Any -> Bool
forall a. Ord a => a -> a -> Bool
> Bounded (Index 'WholeDomain Any) => Index 'WholeDomain Any
forall a. Bounded a => a
maxBound @(Index 'WholeDomain _) =
String -> Index 'WholeDomain level
forall a. HasCallStack => String -> a
error String
"Index@WholeDomain.toEnum: bad argument"
| Bool
otherwise =
Word32 -> Index 'WholeDomain level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index (Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ix)
instance Buildable (Index derivationType level) where
build :: Index derivationType level -> Builder
build (Index Word32
ix) = String -> Builder
forall a. IsString a => String -> a
fromString (Word32 -> String
forall a. Show a => a -> String
show Word32
ix)
instance
( Enum (Index derivation level)
, Bounded (Index derivation level)
) => FromText (Index derivation level) where
fromText :: Text -> Either TextDecodingError (Index derivation level)
fromText = Text -> Either TextDecodingError Int
forall a. FromText a => Text -> Either TextDecodingError a
fromText (Text -> Either TextDecodingError Int)
-> (Int -> Either TextDecodingError (Index derivation level))
-> Text
-> Either TextDecodingError (Index derivation level)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \Int
n -> case Int -> Maybe (Index derivation level)
forall a. (Enum a, Bounded a) => Int -> Maybe a
toEnumMay Int
n of
Just Index derivation level
ix -> Index derivation level
-> Either TextDecodingError (Index derivation level)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Index derivation level
ix
Maybe (Index derivation level)
Nothing -> TextDecodingError
-> Either TextDecodingError (Index derivation level)
forall a b. a -> Either a b
Left (TextDecodingError
-> Either TextDecodingError (Index derivation level))
-> TextDecodingError
-> Either TextDecodingError (Index derivation level)
forall a b. (a -> b) -> a -> b
$ String -> TextDecodingError
TextDecodingError (String -> TextDecodingError) -> String -> TextDecodingError
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
[ String
"Couldn't parse derivation index. Expected an integer between"
, Index derivation level -> String
forall a. Show a => a -> String
show (Bounded (Index derivation level) => Index derivation level
forall a. Bounded a => a
minBound @(Index derivation level))
, String
"and"
, Index derivation level -> String
forall a. Show a => a -> String
show (Bounded (Index derivation level) => Index derivation level
forall a. Bounded a => a
maxBound @(Index derivation level))
]
class LiftIndex derivation where
liftIndex :: Index derivation level -> Index 'WholeDomain level
instance LiftIndex 'Hardened where
liftIndex :: Index 'Hardened level -> Index 'WholeDomain level
liftIndex (Index Word32
ix) = Word32 -> Index 'WholeDomain level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index Word32
ix
instance LiftIndex 'Soft where
liftIndex :: Index 'Soft level -> Index 'WholeDomain level
liftIndex (Index Word32
ix) = Word32 -> Index 'WholeDomain level
forall (derivationType :: DerivationType) (level :: Depth).
Word32 -> Index derivationType level
Index Word32
ix
newtype DerivationPrefix = DerivationPrefix
( Index 'Hardened 'PurposeK
, Index 'Hardened 'CoinTypeK
, Index 'Hardened 'AccountK
) deriving (Int -> DerivationPrefix -> ShowS
[DerivationPrefix] -> ShowS
DerivationPrefix -> String
(Int -> DerivationPrefix -> ShowS)
-> (DerivationPrefix -> String)
-> ([DerivationPrefix] -> ShowS)
-> Show DerivationPrefix
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DerivationPrefix] -> ShowS
$cshowList :: [DerivationPrefix] -> ShowS
show :: DerivationPrefix -> String
$cshow :: DerivationPrefix -> String
showsPrec :: Int -> DerivationPrefix -> ShowS
$cshowsPrec :: Int -> DerivationPrefix -> ShowS
Show, (forall x. DerivationPrefix -> Rep DerivationPrefix x)
-> (forall x. Rep DerivationPrefix x -> DerivationPrefix)
-> Generic DerivationPrefix
forall x. Rep DerivationPrefix x -> DerivationPrefix
forall x. DerivationPrefix -> Rep DerivationPrefix x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DerivationPrefix x -> DerivationPrefix
$cfrom :: forall x. DerivationPrefix -> Rep DerivationPrefix x
Generic, DerivationPrefix -> DerivationPrefix -> Bool
(DerivationPrefix -> DerivationPrefix -> Bool)
-> (DerivationPrefix -> DerivationPrefix -> Bool)
-> Eq DerivationPrefix
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DerivationPrefix -> DerivationPrefix -> Bool
$c/= :: DerivationPrefix -> DerivationPrefix -> Bool
== :: DerivationPrefix -> DerivationPrefix -> Bool
$c== :: DerivationPrefix -> DerivationPrefix -> Bool
Eq, Eq DerivationPrefix
Eq DerivationPrefix
-> (DerivationPrefix -> DerivationPrefix -> Ordering)
-> (DerivationPrefix -> DerivationPrefix -> Bool)
-> (DerivationPrefix -> DerivationPrefix -> Bool)
-> (DerivationPrefix -> DerivationPrefix -> Bool)
-> (DerivationPrefix -> DerivationPrefix -> Bool)
-> (DerivationPrefix -> DerivationPrefix -> DerivationPrefix)
-> (DerivationPrefix -> DerivationPrefix -> DerivationPrefix)
-> Ord DerivationPrefix
DerivationPrefix -> DerivationPrefix -> Bool
DerivationPrefix -> DerivationPrefix -> Ordering
DerivationPrefix -> DerivationPrefix -> DerivationPrefix
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 :: DerivationPrefix -> DerivationPrefix -> DerivationPrefix
$cmin :: DerivationPrefix -> DerivationPrefix -> DerivationPrefix
max :: DerivationPrefix -> DerivationPrefix -> DerivationPrefix
$cmax :: DerivationPrefix -> DerivationPrefix -> DerivationPrefix
>= :: DerivationPrefix -> DerivationPrefix -> Bool
$c>= :: DerivationPrefix -> DerivationPrefix -> Bool
> :: DerivationPrefix -> DerivationPrefix -> Bool
$c> :: DerivationPrefix -> DerivationPrefix -> Bool
<= :: DerivationPrefix -> DerivationPrefix -> Bool
$c<= :: DerivationPrefix -> DerivationPrefix -> Bool
< :: DerivationPrefix -> DerivationPrefix -> Bool
$c< :: DerivationPrefix -> DerivationPrefix -> Bool
compare :: DerivationPrefix -> DerivationPrefix -> Ordering
$ccompare :: DerivationPrefix -> DerivationPrefix -> Ordering
$cp1Ord :: Eq DerivationPrefix
Ord)
instance NFData DerivationPrefix
instance ToText DerivationPrefix where
toText :: DerivationPrefix -> Text
toText (DerivationPrefix (Index 'Hardened 'PurposeK
purpose, Index 'Hardened 'CoinTypeK
coinType, Index 'Hardened 'AccountK
account))
= Text -> [Text] -> Text
T.intercalate Text
"/"
([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (Word32 -> Text) -> [Word32] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Word32 -> Text
forall a. ToText a => a -> Text
toText
[Index 'Hardened 'PurposeK -> Word32
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Word32
getIndex Index 'Hardened 'PurposeK
purpose, Index 'Hardened 'CoinTypeK -> Word32
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Word32
getIndex Index 'Hardened 'CoinTypeK
coinType, Index 'Hardened 'AccountK -> Word32
forall (derivationType :: DerivationType) (level :: Depth).
Index derivationType level -> Word32
getIndex Index 'Hardened 'AccountK
account]
instance FromText DerivationPrefix where
fromText :: Text -> Either TextDecodingError DerivationPrefix
fromText Text
txt =
(Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK)
-> DerivationPrefix
DerivationPrefix ((Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK)
-> DerivationPrefix)
-> Either
TextDecodingError
(Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK)
-> Either TextDecodingError DerivationPrefix
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case Text -> Text -> [Text]
T.splitOn Text
"/" Text
txt of
[Text
purposeT, Text
coinTypeT, Text
accountT] -> (,,)
(Index 'Hardened 'PurposeK
-> Index 'Hardened 'CoinTypeK
-> Index 'Hardened 'AccountK
-> (Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK))
-> Either TextDecodingError (Index 'Hardened 'PurposeK)
-> Either
TextDecodingError
(Index 'Hardened 'CoinTypeK
-> Index 'Hardened 'AccountK
-> (Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Either TextDecodingError (Index 'Hardened 'PurposeK)
forall a. FromText a => Text -> Either TextDecodingError a
fromText Text
purposeT
Either
TextDecodingError
(Index 'Hardened 'CoinTypeK
-> Index 'Hardened 'AccountK
-> (Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK))
-> Either TextDecodingError (Index 'Hardened 'CoinTypeK)
-> Either
TextDecodingError
(Index 'Hardened 'AccountK
-> (Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Either TextDecodingError (Index 'Hardened 'CoinTypeK)
forall a. FromText a => Text -> Either TextDecodingError a
fromText Text
coinTypeT
Either
TextDecodingError
(Index 'Hardened 'AccountK
-> (Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK))
-> Either TextDecodingError (Index 'Hardened 'AccountK)
-> Either
TextDecodingError
(Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Text -> Either TextDecodingError (Index 'Hardened 'AccountK)
forall a. FromText a => Text -> Either TextDecodingError a
fromText Text
accountT
[Text]
_ ->
TextDecodingError
-> Either
TextDecodingError
(Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK)
forall a b. a -> Either a b
Left (TextDecodingError
-> Either
TextDecodingError
(Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK))
-> TextDecodingError
-> Either
TextDecodingError
(Index 'Hardened 'PurposeK, Index 'Hardened 'CoinTypeK,
Index 'Hardened 'AccountK)
forall a b. (a -> b) -> a -> b
$ String -> TextDecodingError
TextDecodingError String
"expected exactly 3 derivation paths"
data DerivationType = Hardened | Soft | WholeDomain
class HardDerivation (key :: Depth -> Type -> Type) where
type AddressIndexDerivationType key :: DerivationType
deriveAccountPrivateKey
:: Passphrase "encryption"
-> key 'RootK XPrv
-> Index 'Hardened 'AccountK
-> key 'AccountK XPrv
deriveAddressPrivateKey
:: Passphrase "encryption"
-> key 'AccountK XPrv
-> Role
-> Index (AddressIndexDerivationType key) 'AddressK
-> key 'AddressK XPrv
class HardDerivation key => SoftDerivation (key :: Depth -> Type -> Type) where
deriveAddressPublicKey
:: key 'AccountK XPub
-> Role
-> Index 'Soft 'AddressK
-> key 'AddressK XPub
class ToRewardAccount k where
toRewardAccount :: k 'AddressK XPub -> RewardAccount
someRewardAccount :: SomeMnemonic -> (XPrv, RewardAccount, NonEmpty DerivationIndex)
deriveRewardAccount
:: ( HardDerivation k
, Bounded (Index (AddressIndexDerivationType k) 'AddressK)
)
=> Passphrase "encryption"
-> k 'RootK XPrv
-> k 'AddressK XPrv
deriveRewardAccount :: Passphrase "encryption" -> k 'RootK XPrv -> k 'AddressK XPrv
deriveRewardAccount Passphrase "encryption"
pwd k 'RootK XPrv
rootPrv =
let accPrv :: k 'AccountK XPrv
accPrv = Passphrase "encryption"
-> k 'RootK XPrv -> Index 'Hardened 'AccountK -> k 'AccountK XPrv
forall (key :: Depth -> * -> *).
HardDerivation key =>
Passphrase "encryption"
-> key 'RootK XPrv
-> Index 'Hardened 'AccountK
-> key 'AccountK XPrv
deriveAccountPrivateKey Passphrase "encryption"
pwd k 'RootK XPrv
rootPrv Index 'Hardened 'AccountK
forall a. Bounded a => a
minBound
in Passphrase "encryption"
-> k 'AccountK XPrv
-> Role
-> Index (AddressIndexDerivationType k) 'AddressK
-> k 'AddressK XPrv
forall (key :: Depth -> * -> *).
HardDerivation key =>
Passphrase "encryption"
-> key 'AccountK XPrv
-> Role
-> Index (AddressIndexDerivationType key) 'AddressK
-> key 'AddressK XPrv
deriveAddressPrivateKey Passphrase "encryption"
pwd k 'AccountK XPrv
accPrv Role
MutableAccount Index (AddressIndexDerivationType k) 'AddressK
forall a. Bounded a => a
minBound
hashVerificationKey
:: WalletKey key
=> KeyRole
-> key depth XPub
-> KeyHash
hashVerificationKey :: KeyRole -> key depth XPub -> KeyHash
hashVerificationKey KeyRole
keyRole =
KeyRole -> ByteString -> KeyHash
KeyHash KeyRole
keyRole (ByteString -> KeyHash)
-> (key depth XPub -> ByteString) -> key depth XPub -> KeyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
forall a. ByteArrayAccess a => a -> ByteString
blake2b224 (ByteString -> ByteString)
-> (key depth XPub -> ByteString) -> key depth XPub -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XPub -> ByteString
xpubPublicKey (XPub -> ByteString)
-> (key depth XPub -> XPub) -> key depth XPub -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. key depth XPub -> XPub
forall (key :: Depth -> * -> *) (depth :: Depth) raw.
WalletKey key =>
key depth raw -> raw
getRawKey
data NetworkDiscriminant = Mainnet | Testnet Nat | Staging Nat
deriving Typeable
class NetworkDiscriminantVal (n :: NetworkDiscriminant) where
networkDiscriminantVal :: Text
instance NetworkDiscriminantVal 'Mainnet where
networkDiscriminantVal :: Text
networkDiscriminantVal =
Text
"mainnet"
instance KnownNat pm => NetworkDiscriminantVal ('Testnet pm) where
networkDiscriminantVal :: Text
networkDiscriminantVal =
Text
"testnet (" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> Integer -> String
forall a b. (a -> b) -> a -> b
$ Proxy pm -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy pm -> Integer) -> Proxy pm -> Integer
forall a b. (a -> b) -> a -> b
$ Proxy pm
forall k (t :: k). Proxy t
Proxy @pm) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
instance KnownNat pm => NetworkDiscriminantVal ('Staging pm) where
networkDiscriminantVal :: Text
networkDiscriminantVal =
Text
"staging (" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> Integer -> String
forall a b. (a -> b) -> a -> b
$ Proxy pm -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy pm -> Integer) -> Proxy pm -> Integer
forall a b. (a -> b) -> a -> b
$ Proxy pm
forall k (t :: k). Proxy t
Proxy @pm) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
class WalletKey (key :: Depth -> Type -> Type) where
changePassphrase
:: (PassphraseScheme, Passphrase "user")
-> (PassphraseScheme, Passphrase "user")
-> key depth XPrv
-> key depth XPrv
publicKey
:: key depth XPrv
-> key depth XPub
digest
:: HashAlgorithm a
=> key depth XPub
-> Digest a
keyTypeDescriptor :: Proxy key -> String
getRawKey
:: key depth raw
-> raw
liftRawKey
:: raw
-> key depth raw
class BoundedAddressLength key where
maxLengthAddressFor
:: Proxy key
-> Address
class MkKeyFingerprint key Address
=> PaymentAddress (network :: NetworkDiscriminant) key where
paymentAddress
:: key 'AddressK XPub
-> Address
liftPaymentAddress
:: KeyFingerprint "payment" key
-> Address
instance PaymentAddress 'Mainnet k => PaymentAddress ('Staging pm) k where
paymentAddress :: k 'AddressK XPub -> Address
paymentAddress = forall (network :: NetworkDiscriminant) (key :: Depth -> * -> *).
PaymentAddress network key =>
key 'AddressK XPub -> Address
forall (key :: Depth -> * -> *).
PaymentAddress 'Mainnet key =>
key 'AddressK XPub -> Address
paymentAddress @'Mainnet
liftPaymentAddress :: KeyFingerprint "payment" k -> Address
liftPaymentAddress = forall (network :: NetworkDiscriminant) (key :: Depth -> * -> *).
PaymentAddress network key =>
KeyFingerprint "payment" key -> Address
forall (key :: Depth -> * -> *).
PaymentAddress 'Mainnet key =>
KeyFingerprint "payment" key -> Address
liftPaymentAddress @'Mainnet
class PaymentAddress network key
=> DelegationAddress (network :: NetworkDiscriminant) key where
delegationAddress
:: key 'AddressK XPub
-> key 'AddressK XPub
-> Address
liftDelegationAddress
:: KeyFingerprint "payment" key
-> key 'AddressK XPub
-> Address
instance DelegationAddress 'Mainnet k => DelegationAddress ('Staging pm) k where
delegationAddress :: k 'AddressK XPub -> k 'AddressK XPub -> Address
delegationAddress = forall (network :: NetworkDiscriminant) (key :: Depth -> * -> *).
DelegationAddress network key =>
key 'AddressK XPub -> key 'AddressK XPub -> Address
forall (key :: Depth -> * -> *).
DelegationAddress 'Mainnet key =>
key 'AddressK XPub -> key 'AddressK XPub -> Address
delegationAddress @'Mainnet
liftDelegationAddress :: KeyFingerprint "payment" k -> k 'AddressK XPub -> Address
liftDelegationAddress = forall (network :: NetworkDiscriminant) (key :: Depth -> * -> *).
DelegationAddress network key =>
KeyFingerprint "payment" key -> key 'AddressK XPub -> Address
forall (key :: Depth -> * -> *).
DelegationAddress 'Mainnet key =>
KeyFingerprint "payment" key -> key 'AddressK XPub -> Address
liftDelegationAddress @'Mainnet
class PersistPrivateKey (key :: Type -> Type) where
serializeXPrv
:: (key XPrv, PassphraseHash)
-> (ByteString, ByteString)
unsafeDeserializeXPrv
:: (ByteString, ByteString)
-> (key XPrv, PassphraseHash)
class PersistPublicKey (key :: Type -> Type) where
serializeXPub
:: key XPub
-> ByteString
unsafeDeserializeXPub
:: ByteString
-> key XPub
newtype KeyFingerprint (s :: Symbol) key = KeyFingerprint ByteString
deriving ((forall x. KeyFingerprint s key -> Rep (KeyFingerprint s key) x)
-> (forall x. Rep (KeyFingerprint s key) x -> KeyFingerprint s key)
-> Generic (KeyFingerprint s key)
forall x. Rep (KeyFingerprint s key) x -> KeyFingerprint s key
forall x. KeyFingerprint s key -> Rep (KeyFingerprint s key) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: Symbol) k (key :: k) x.
Rep (KeyFingerprint s key) x -> KeyFingerprint s key
forall (s :: Symbol) k (key :: k) x.
KeyFingerprint s key -> Rep (KeyFingerprint s key) x
$cto :: forall (s :: Symbol) k (key :: k) x.
Rep (KeyFingerprint s key) x -> KeyFingerprint s key
$cfrom :: forall (s :: Symbol) k (key :: k) x.
KeyFingerprint s key -> Rep (KeyFingerprint s key) x
Generic, Int -> KeyFingerprint s key -> ShowS
[KeyFingerprint s key] -> ShowS
KeyFingerprint s key -> String
(Int -> KeyFingerprint s key -> ShowS)
-> (KeyFingerprint s key -> String)
-> ([KeyFingerprint s key] -> ShowS)
-> Show (KeyFingerprint s key)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (s :: Symbol) k (key :: k).
Int -> KeyFingerprint s key -> ShowS
forall (s :: Symbol) k (key :: k). [KeyFingerprint s key] -> ShowS
forall (s :: Symbol) k (key :: k). KeyFingerprint s key -> String
showList :: [KeyFingerprint s key] -> ShowS
$cshowList :: forall (s :: Symbol) k (key :: k). [KeyFingerprint s key] -> ShowS
show :: KeyFingerprint s key -> String
$cshow :: forall (s :: Symbol) k (key :: k). KeyFingerprint s key -> String
showsPrec :: Int -> KeyFingerprint s key -> ShowS
$cshowsPrec :: forall (s :: Symbol) k (key :: k).
Int -> KeyFingerprint s key -> ShowS
Show, KeyFingerprint s key -> KeyFingerprint s key -> Bool
(KeyFingerprint s key -> KeyFingerprint s key -> Bool)
-> (KeyFingerprint s key -> KeyFingerprint s key -> Bool)
-> Eq (KeyFingerprint s key)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (s :: Symbol) k (key :: k).
KeyFingerprint s key -> KeyFingerprint s key -> Bool
/= :: KeyFingerprint s key -> KeyFingerprint s key -> Bool
$c/= :: forall (s :: Symbol) k (key :: k).
KeyFingerprint s key -> KeyFingerprint s key -> Bool
== :: KeyFingerprint s key -> KeyFingerprint s key -> Bool
$c== :: forall (s :: Symbol) k (key :: k).
KeyFingerprint s key -> KeyFingerprint s key -> Bool
Eq, Eq (KeyFingerprint s key)
Eq (KeyFingerprint s key)
-> (KeyFingerprint s key -> KeyFingerprint s key -> Ordering)
-> (KeyFingerprint s key -> KeyFingerprint s key -> Bool)
-> (KeyFingerprint s key -> KeyFingerprint s key -> Bool)
-> (KeyFingerprint s key -> KeyFingerprint s key -> Bool)
-> (KeyFingerprint s key -> KeyFingerprint s key -> Bool)
-> (KeyFingerprint s key
-> KeyFingerprint s key -> KeyFingerprint s key)
-> (KeyFingerprint s key
-> KeyFingerprint s key -> KeyFingerprint s key)
-> Ord (KeyFingerprint s key)
KeyFingerprint s key -> KeyFingerprint s key -> Bool
KeyFingerprint s key -> KeyFingerprint s key -> Ordering
KeyFingerprint s key
-> KeyFingerprint s key -> KeyFingerprint s key
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
forall (s :: Symbol) k (key :: k). Eq (KeyFingerprint s key)
forall (s :: Symbol) k (key :: k).
KeyFingerprint s key -> KeyFingerprint s key -> Bool
forall (s :: Symbol) k (key :: k).
KeyFingerprint s key -> KeyFingerprint s key -> Ordering
forall (s :: Symbol) k (key :: k).
KeyFingerprint s key
-> KeyFingerprint s key -> KeyFingerprint s key
min :: KeyFingerprint s key
-> KeyFingerprint s key -> KeyFingerprint s key
$cmin :: forall (s :: Symbol) k (key :: k).
KeyFingerprint s key
-> KeyFingerprint s key -> KeyFingerprint s key
max :: KeyFingerprint s key
-> KeyFingerprint s key -> KeyFingerprint s key
$cmax :: forall (s :: Symbol) k (key :: k).
KeyFingerprint s key
-> KeyFingerprint s key -> KeyFingerprint s key
>= :: KeyFingerprint s key -> KeyFingerprint s key -> Bool
$c>= :: forall (s :: Symbol) k (key :: k).
KeyFingerprint s key -> KeyFingerprint s key -> Bool
> :: KeyFingerprint s key -> KeyFingerprint s key -> Bool
$c> :: forall (s :: Symbol) k (key :: k).
KeyFingerprint s key -> KeyFingerprint s key -> Bool
<= :: KeyFingerprint s key -> KeyFingerprint s key -> Bool
$c<= :: forall (s :: Symbol) k (key :: k).
KeyFingerprint s key -> KeyFingerprint s key -> Bool
< :: KeyFingerprint s key -> KeyFingerprint s key -> Bool
$c< :: forall (s :: Symbol) k (key :: k).
KeyFingerprint s key -> KeyFingerprint s key -> Bool
compare :: KeyFingerprint s key -> KeyFingerprint s key -> Ordering
$ccompare :: forall (s :: Symbol) k (key :: k).
KeyFingerprint s key -> KeyFingerprint s key -> Ordering
$cp1Ord :: forall (s :: Symbol) k (key :: k). Eq (KeyFingerprint s key)
Ord)
instance NFData (KeyFingerprint s key)
class Show from => MkKeyFingerprint (key :: Depth -> Type -> Type) from where
paymentKeyFingerprint
:: from
-> Either
(ErrMkKeyFingerprint key from)
(KeyFingerprint "payment" key)
data ErrMkKeyFingerprint key from
= ErrInvalidAddress from (Proxy key) deriving (Int -> ErrMkKeyFingerprint key from -> ShowS
[ErrMkKeyFingerprint key from] -> ShowS
ErrMkKeyFingerprint key from -> String
(Int -> ErrMkKeyFingerprint key from -> ShowS)
-> (ErrMkKeyFingerprint key from -> String)
-> ([ErrMkKeyFingerprint key from] -> ShowS)
-> Show (ErrMkKeyFingerprint key from)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (key :: k) from.
Show from =>
Int -> ErrMkKeyFingerprint key from -> ShowS
forall k (key :: k) from.
Show from =>
[ErrMkKeyFingerprint key from] -> ShowS
forall k (key :: k) from.
Show from =>
ErrMkKeyFingerprint key from -> String
showList :: [ErrMkKeyFingerprint key from] -> ShowS
$cshowList :: forall k (key :: k) from.
Show from =>
[ErrMkKeyFingerprint key from] -> ShowS
show :: ErrMkKeyFingerprint key from -> String
$cshow :: forall k (key :: k) from.
Show from =>
ErrMkKeyFingerprint key from -> String
showsPrec :: Int -> ErrMkKeyFingerprint key from -> ShowS
$cshowsPrec :: forall k (key :: k) from.
Show from =>
Int -> ErrMkKeyFingerprint key from -> ShowS
Show, ErrMkKeyFingerprint key from
-> ErrMkKeyFingerprint key from -> Bool
(ErrMkKeyFingerprint key from
-> ErrMkKeyFingerprint key from -> Bool)
-> (ErrMkKeyFingerprint key from
-> ErrMkKeyFingerprint key from -> Bool)
-> Eq (ErrMkKeyFingerprint key from)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (key :: k) from.
Eq from =>
ErrMkKeyFingerprint key from
-> ErrMkKeyFingerprint key from -> Bool
/= :: ErrMkKeyFingerprint key from
-> ErrMkKeyFingerprint key from -> Bool
$c/= :: forall k (key :: k) from.
Eq from =>
ErrMkKeyFingerprint key from
-> ErrMkKeyFingerprint key from -> Bool
== :: ErrMkKeyFingerprint key from
-> ErrMkKeyFingerprint key from -> Bool
$c== :: forall k (key :: k) from.
Eq from =>
ErrMkKeyFingerprint key from
-> ErrMkKeyFingerprint key from -> Bool
Eq)
hex :: ByteArrayAccess bin => bin -> ByteString
hex :: bin -> ByteString
hex = Base -> bin -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> bout
convertToBase Base
Base16
fromHex :: ByteArray bout => ByteString -> Either String bout
fromHex :: ByteString -> Either String bout
fromHex = Base -> ByteString -> Either String bout
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> Either String bout
convertFromBase Base
Base16