content: module Cardano.Wallet.Kernel.Decrypt
      ( decryptAddress
      , eskToWalletDecrCredentials
      , selectOwnAddresses
      , WalletDecrCredentials
      ) where
  
  import           Universum
  
  import           Formatting (build, sformat)
  
  import           Cardano.Wallet.API.V1.Types as V1
  import           Pos.Core (aaPkDerivationPath, addrAttributesUnwrapped,
                       makeRootPubKeyAddress)
  import           Pos.Core.NetworkMagic (NetworkMagic)
  import           Pos.Crypto (EncryptedSecretKey, HDPassphrase, PublicKey,
                       deriveHDPassphrase, encToPublic, unpackHDAddressAttr)
  
  
  type WalletDecrCredentials = (HDPassphrase, V1.WalletId)
  
  -- | There's a secret key for regular wallet or a public key for external wallet.
  eskToWalletDecrCredentials :: NetworkMagic -> EncryptedSecretKey -> WalletDecrCredentials
  eskToWalletDecrCredentials nm esk = credentialsFromPublicKey nm $ encToPublic esk
  
  credentialsFromPublicKey :: NetworkMagic -> PublicKey -> WalletDecrCredentials
  credentialsFromPublicKey nm publicKey = (hdPassword, walletId)
    where
      hdPassword = deriveHDPassphrase publicKey
  
      -- When migrating from 'Pos.Wallet.Web.Tracking.Decrypt' this type is
      -- changed from 'CId Wal' to 'V1.WalletId'
      walletId   = V1.WalletId . (sformat build) $ makeRootPubKeyAddress nm publicKey
  
  selectOwnAddresses
      :: WalletDecrCredentials
      -> (a -> Address)
      -> [a]
      -> [(a, V1.WAddressMeta)]
  selectOwnAddresses wdc getAddr =
      mapMaybe (\a -> (a,) <$> decryptAddress wdc (getAddr a))
  
  decryptAddress :: WalletDecrCredentials -> Address -> Maybe V1.WAddressMeta
  decryptAddress (hdPass, wCId) addr = do
      hdPayload <- aaPkDerivationPath $ addrAttributesUnwrapped addr
      derPath <- unpackHDAddressAttr hdPass hdPayload
      case derPath of
          [a,b] -> Just $ WAddressMeta wCId a b (V1 addr)
          _     -> Nothing
  