Skip to content

Commit

Permalink
introduce GetAccount type class
Browse files Browse the repository at this point in the history
  • Loading branch information
paweljakubas committed May 11, 2021
1 parent 62ae281 commit 71ca86c
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 61 deletions.
55 changes: 6 additions & 49 deletions lib/core/src/Cardano/Wallet.hs
Expand Up @@ -158,8 +158,7 @@ module Cardano.Wallet

-- ** Root Key
, withRootKey
, derivePublicKeyShelley
, derivePublicKeyShared
, derivePublicKey
, readPublicAccountKey
, signMetadataWith
, ErrWithRootKey (..)
Expand Down Expand Up @@ -250,6 +249,7 @@ import Cardano.Wallet.Primitive.AddressDerivation.Shelley
import Cardano.Wallet.Primitive.AddressDiscovery
( CompareDiscovery (..)
, GenChange (..)
, GetAccount (..)
, IsOurs (..)
, IsOwned (..)
, KnownAddresses (..)
Expand All @@ -266,7 +266,7 @@ import Cardano.Wallet.Primitive.AddressDiscovery.Sequential
, purposeBIP44
)
import Cardano.Wallet.Primitive.AddressDiscovery.SharedState
( ErrAddCosigner (..), SharedState, accountPublicKey, addCosignerAccXPub )
( ErrAddCosigner (..), SharedState, addCosignerAccXPub )
import Cardano.Wallet.Primitive.CoinSelection.MA.RoundRobin
( SelectionError (..)
, SelectionResult (..)
Expand Down Expand Up @@ -2104,69 +2104,26 @@ signMetadataWith ctx wid pwd (role_, ix) metadata = db & \DBLayer{..} -> do
where
db = ctx ^. dbLayer @IO @s @k

-- | Derive public key from a wallet's account key.
derivePublicKeyShelley
:: forall ctx s k n.
( HasDBLayer IO s k ctx
, SoftDerivation k
, s ~ SeqState n k
)
=> ctx
-> WalletId
-> Role
-> DerivationIndex
-> ExceptT ErrDerivePublicKey IO (k 'AddressK XPub)
derivePublicKeyShelley ctx =
derivePublicKey @ctx @s @k ctx toAccXPubShelley

derivePublicKeyShared
:: forall ctx s k n.
( HasDBLayer IO s k ctx
, SoftDerivation k
, s ~ SharedState n k
)
=> ctx
-> WalletId
-> Role
-> DerivationIndex
-> ExceptT ErrDerivePublicKey IO (k 'AddressK XPub)
derivePublicKeyShared ctx =
derivePublicKey @ctx @s @k ctx toAccXPubShared

toAccXPubShared
:: SharedState n k
-> k 'AccountK XPub
toAccXPubShared = accountPublicKey

toAccXPubShelley
:: SeqState n k
-> k 'AccountK XPub
toAccXPubShelley s =
-- NOTE: Alternatively, we could use 'internalPool', they share the same
-- account public key.
let (Seq.ParentContextUtxo acctK) = Seq.context $ Seq.externalPool s
in acctK

derivePublicKey
:: forall ctx s k.
( HasDBLayer IO s k ctx
, SoftDerivation k
, GetAccount s k
)
=> ctx
-> (s -> k 'AccountK XPub)
-> WalletId
-> Role
-> DerivationIndex
-> ExceptT ErrDerivePublicKey IO (k 'AddressK XPub)
derivePublicKey ctx toAccXPub wid role_ ix = db & \DBLayer{..} -> do
derivePublicKey ctx wid role_ ix = db & \DBLayer{..} -> do
addrIx <- withExceptT ErrDerivePublicKeyInvalidIndex $ guardSoftIndex ix

cp <- mapExceptT atomically
$ withExceptT ErrDerivePublicKeyNoSuchWallet
$ withNoSuchWallet wid
$ readCheckpoint wid

let acctK = toAccXPub $ getState cp
let acctK = getAccount $ getState cp
let addrK = deriveAddressPublicKey acctK role_ addrIx

return addrK
Expand Down
4 changes: 2 additions & 2 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Expand Up @@ -2178,7 +2178,7 @@ derivePublicKeyShelley
-> Handler ApiVerificationKeyShelley
derivePublicKeyShelley ctx (ApiT wid) (ApiT role_) (ApiT ix) = do
withWorkerCtx @_ @s @k ctx wid liftE liftE $ \wrk -> do
k <- liftHandler $ W.derivePublicKeyShelley @_ @s @k @n wrk wid role_ ix
k <- liftHandler $ W.derivePublicKey @_ @s @k wrk wid role_ ix
pure $ ApiVerificationKeyShelley (xpubPublicKey $ getRawKey k, role_)

derivePublicKeyShared
Expand All @@ -2196,7 +2196,7 @@ derivePublicKeyShared
-> Handler ApiVerificationKeyShared
derivePublicKeyShared ctx (ApiT wid) (ApiT role_) (ApiT ix) hashed = do
withWorkerCtx @_ @s @k ctx wid liftE liftE $ \wrk -> do
k <- liftHandler $ W.derivePublicKeyShared @_ @s @k @n wrk wid role_ ix
k <- liftHandler $ W.derivePublicKey @_ @s @k wrk wid role_ ix
pure $ ApiVerificationKeyShared (computePayload k, role_) hashing
where
hashing = case hashed of
Expand Down
8 changes: 7 additions & 1 deletion lib/core/src/Cardano/Wallet/Primitive/AddressDiscovery.hs
Expand Up @@ -3,6 +3,7 @@
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
Expand All @@ -26,13 +27,14 @@ module Cardano.Wallet.Primitive.AddressDiscovery
, CompareDiscovery(..)
, KnownAddresses(..)
, GetPurpose (..)
, GetAccount (..)
, coinTypeAda
) where

import Prelude

import Cardano.Crypto.Wallet
( XPrv )
( XPrv, XPub )
import Cardano.Wallet.Primitive.AddressDerivation
( Depth (..)
, DerivationIndex (..)
Expand Down Expand Up @@ -156,3 +158,7 @@ coinTypeAda = toEnum 0x80000717
-- It is used for geting purpose for a given key.
class GetPurpose (key :: Depth -> Type -> Type) where
getPurpose :: Index 'Hardened 'PurposeK

-- It is used for geting account public key for a given state.
class GetAccount s (key :: Depth -> Type -> Type) | s -> key where
getAccount :: s -> key 'AccountK XPub
Expand Up @@ -105,6 +105,7 @@ import Cardano.Wallet.Primitive.AddressDerivation.SharedKey
import Cardano.Wallet.Primitive.AddressDiscovery
( CompareDiscovery (..)
, GenChange (..)
, GetAccount (..)
, GetPurpose (..)
, IsOurs (..)
, IsOwned (..)
Expand Down Expand Up @@ -1002,3 +1003,10 @@ instance
) => KnownAddresses (SeqAnyState n k p)
where
knownAddresses (SeqAnyState s) = knownAddresses s

instance GetAccount (SeqState n k) k where
getAccount s =
-- NOTE: Alternatively, we could use 'internalPool', they share the same
-- account public key.
let (ParentContextUtxo acctK) = context $ externalPool s
in acctK
Expand Up @@ -33,7 +33,6 @@ module Cardano.Wallet.Primitive.AddressDiscovery.SharedState
, isShared
, retrieveAllCosigners
, walletCreationInvariant
, accountPublicKey
) where

import Prelude
Expand Down Expand Up @@ -64,7 +63,7 @@ import Cardano.Wallet.Primitive.AddressDerivation
import Cardano.Wallet.Primitive.AddressDerivation.SharedKey
( SharedKey (..), purposeCIP1854 )
import Cardano.Wallet.Primitive.AddressDiscovery
( IsOurs (..), coinTypeAda )
( GetAccount (..), IsOurs (..), coinTypeAda )
import Cardano.Wallet.Primitive.AddressDiscovery.Script
( CredentialType (..) )
import Cardano.Wallet.Primitive.AddressDiscovery.Sequential
Expand Down Expand Up @@ -200,13 +199,6 @@ instance
( NFData (k 'AccountK XPub)
) => NFData (SharedStatePending k)

accountPublicKey :: SharedState n k -> k 'AccountK XPub
accountPublicKey (SharedState _ (PendingFields pending)) =
pendingSharedStateAccountKey pending
accountPublicKey (SharedState _ (ReadyFields pool)) =
let (ParentContextShared accXPub _ _) = context pool
in accXPub

-- | Create a new SharedState from public account key.
mkSharedStateFromAccountXPub
:: (SupportsSharedState n k, WalletKey k, k ~ SharedKey)
Expand Down Expand Up @@ -425,3 +417,10 @@ instance IsOurs (SharedState n k) Address where

instance IsOurs (SharedState n k) RewardAccount where
isOurs _account state = (Nothing, state)

instance GetAccount (SharedState n k) k where
getAccount (SharedState _ (PendingFields pending)) =
pendingSharedStateAccountKey pending
getAccount (SharedState _ (ReadyFields pool)) =
let (ParentContextShared accXPub _ _) = context pool
in accXPub

0 comments on commit 71ca86c

Please sign in to comment.