packages feed

morley-client-0.3.0: src/Morley/Client/Action/Reveal.hs

-- SPDX-FileCopyrightText: 2022 Oxhead Alpha
-- SPDX-License-Identifier: LicenseRef-MIT-OA

-- | Functions to reveal keys via node RPC.
module Morley.Client.Action.Reveal
  ( RevealData (..)
  , revealKey
  , revealKeyUnlessRevealed
  ) where

import Fmt ((|+))

import Morley.Client.Action.Common hiding (revealKeyUnlessRevealed)
import Morley.Client.Action.Operation
import Morley.Client.Logging
import Morley.Client.RPC.Class
import Morley.Client.RPC.Error
import Morley.Client.RPC.Getters
import Morley.Client.RPC.Types
import Morley.Client.TezosClient (HasTezosClient)
import Morley.Client.Types
import Morley.Tezos.Address (mkKeyAddress)
import Morley.Tezos.Address.Alias (AddressOrAlias(..))
import Morley.Tezos.Core (Mutez)
import Morley.Tezos.Crypto (PublicKey)

-- | Reveal given key.
--
-- Note that sender is implicitly defined by the key being revealed, as you can
-- only reveal your own key.
--
-- This is a variation of key revealing method that tries to use solely RPC.
revealKey
-- TODO [#873] remove HasTezosClient dependency
  :: forall m env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     )
  => PublicKey
  -> Maybe Mutez
  -> m OperationHash
revealKey rdPublicKey rdMbFee =
  fmap fst . runOperationsNonEmpty (AddressResolved sender) . one $ OpReveal RevealData{..}
  where
    sender = mkKeyAddress rdPublicKey

-- | Reveal given key.
--
-- Note that sender is implicitly defined by the key being revealed, as you can
-- only reveal your own key.
revealKeyUnlessRevealed
-- TODO [#873] remove HasTezosClient dependency
  :: forall m env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     )
  => PublicKey
  -> Maybe Mutez
  -> m ()
revealKeyUnlessRevealed key mbFee = do
  -- An optimization for the average case, but we can't rely on it in
  -- distributed environment
  let sender = mkKeyAddress key
  getManagerKey sender >>= \case
    Just _  -> logDebug $ sender |+ " address has already revealed key"
    Nothing -> ignoreAlreadyRevealedError . void $ revealKey key mbFee
  where
    ignoreAlreadyRevealedError = flip catch \case
      RunCodeErrors [PreviouslyRevealedKey _] -> pass
      e -> throwM e