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

-- | Utilities for resolving addresses and aliases.
module Morley.Client.TezosClient.Resolve
  ( ResolveError(..)
  , Resolve(..)
  , resolveAddress
  , resolveAddressMaybe
  , getAlias
  , getAliasMaybe
  , getTezosClientConfig
  , resolveAddressWithAlias
  , resolveAddressWithAliasMaybe
  ) where

import Data.Constraint ((\\))
import Fmt (pretty)

import Morley.Client.TezosClient.Class qualified as Class
import Morley.Client.TezosClient.Config
import Morley.Client.TezosClient.Types.Errors
import Morley.Client.Types
import Morley.Client.Types.AliasesAndAddresses
import Morley.Tezos.Address
import Morley.Tezos.Address.Alias
import Morley.Tezos.Address.Kinds
import Morley.Util.Constrained

class Resolve addressOrAlias where
  type ResolvedAddress addressOrAlias :: Type
  type ResolvedAlias addressOrAlias :: Type
  type ResolvedAddressAndAlias addressOrAlias :: Type

  -- | Looks up the address associated with the given @addressOrAlias@.
  --
  -- When the alias is associated with __both__ an implicit and a contract address:
  --
  -- * The 'SomeAddressOrAlias' instance will return 'REAmbiguousAlias',
  --   unless the alias is prefixed with @implicit:@ or @contract:@ to disambiguate.
  -- * The 'AddressOrAlias' instance will return the address with the requested kind.
  resolveAddressEither
    :: (Class.HasTezosClient m)
    => addressOrAlias
    -> m (Either ResolveError (ResolvedAddress addressOrAlias))

  {- | Looks up the alias associated with the given @addressOrAlias@.

  When the alias is associated with __both__ an implicit and a contract address:

  * The 'SomeAddressOrAlias' instance will return 'REAmbiguousAlias',
    unless the alias is prefixed with @implicit:@ or @contract:@ to disambiguate.
  * The 'AddressOrAlias' instance will return the alias of the address with the requested kind.

  The primary (and probably only) reason this function exists is that
  @octez-client sign@ command only works with aliases. It was
  reported upstream: <https://gitlab.com/tezos/tezos/-/issues/836>.
  -}
  getAliasEither
    :: (Class.HasTezosClient m)
    => addressOrAlias
    -> m (Either ResolveError (ResolvedAlias addressOrAlias))

  -- | Resolve both address and alias at the same time
  resolveAddressWithAliasEither
    :: (Class.HasTezosClient m)
    => addressOrAlias
    -> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))

instance L1AddressKind kind => Resolve (KindedAddress kind) where
  type ResolvedAddress (KindedAddress kind) = KindedAddress kind
  type ResolvedAlias (KindedAddress kind) = Alias kind
  type ResolvedAddressAndAlias (KindedAddress kind) = AddressWithAlias kind

  resolveAddressEither
    :: (Class.HasTezosClient m)
    => KindedAddress kind -> m (Either ResolveError (KindedAddress kind))
  resolveAddressEither :: forall (m :: * -> *).
HasTezosClient m =>
KindedAddress kind -> m (Either ResolveError (KindedAddress kind))
resolveAddressEither = Either ResolveError (KindedAddress kind)
-> m (Either ResolveError (KindedAddress kind))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ResolveError (KindedAddress kind)
 -> m (Either ResolveError (KindedAddress kind)))
-> (KindedAddress kind -> Either ResolveError (KindedAddress kind))
-> KindedAddress kind
-> m (Either ResolveError (KindedAddress kind))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KindedAddress kind -> Either ResolveError (KindedAddress kind)
forall a b. b -> Either a b
Right

  getAliasEither
    :: (Class.HasTezosClient m)
    => KindedAddress kind -> m (Either ResolveError (Alias kind))
  getAliasEither :: forall (m :: * -> *).
HasTezosClient m =>
KindedAddress kind -> m (Either ResolveError (Alias kind))
getAliasEither KindedAddress kind
addr
    = ResolveError
-> Maybe (Alias kind) -> Either ResolveError (Alias kind)
forall l r. l -> Maybe r -> Either l r
maybeToRight (KindedAddress kind -> ResolveError
forall (kind :: AddressKind). KindedAddress kind -> ResolveError
REAddressNotFound KindedAddress kind
addr)
    (Maybe (Alias kind) -> Either ResolveError (Alias kind))
-> (AliasesAndAddresses -> Maybe (Alias kind))
-> AliasesAndAddresses
-> Either ResolveError (Alias kind)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KindedAddress kind -> AliasesAndAddresses -> Maybe (Alias kind)
forall (kind :: AddressKind).
KindedAddress kind -> AliasesAndAddresses -> Maybe (Alias kind)
lookupAlias KindedAddress kind
addr (AliasesAndAddresses -> Either ResolveError (Alias kind))
-> m AliasesAndAddresses -> m (Either ResolveError (Alias kind))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m AliasesAndAddresses
forall (m :: * -> *). HasTezosClient m => m AliasesAndAddresses
Class.getAliasesAndAddresses

  resolveAddressWithAliasEither :: forall (m :: * -> *).
HasTezosClient m =>
KindedAddress kind
-> m (Either
        ResolveError (ResolvedAddressAndAlias (KindedAddress kind)))
resolveAddressWithAliasEither KindedAddress kind
addr = (Alias kind -> AddressWithAlias kind)
-> Either ResolveError (Alias kind)
-> Either ResolveError (AddressWithAlias kind)
forall a b.
(a -> b) -> Either ResolveError a -> Either ResolveError b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (KindedAddress kind -> Alias kind -> AddressWithAlias kind
forall (kind :: AddressKind).
KindedAddress kind -> Alias kind -> AddressWithAlias kind
AddressWithAlias KindedAddress kind
addr) (Either ResolveError (Alias kind)
 -> Either ResolveError (AddressWithAlias kind))
-> m (Either ResolveError (Alias kind))
-> m (Either ResolveError (AddressWithAlias kind))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> KindedAddress kind
-> m (Either ResolveError (ResolvedAlias (KindedAddress kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
KindedAddress kind
-> m (Either ResolveError (ResolvedAlias (KindedAddress kind)))
getAliasEither KindedAddress kind
addr

instance Resolve (Alias kind) where
  type ResolvedAddress (Alias kind) = KindedAddress kind
  type ResolvedAlias (Alias kind) = Alias kind
  type ResolvedAddressAndAlias (Alias kind) = AddressWithAlias kind

  resolveAddressEither
    :: (Class.HasTezosClient m)
    => Alias kind -> m (Either ResolveError (KindedAddress kind))
  resolveAddressEither :: forall (m :: * -> *).
HasTezosClient m =>
Alias kind -> m (Either ResolveError (KindedAddress kind))
resolveAddressEither Alias kind
alias = do
    AliasesAndAddresses
aas <- m AliasesAndAddresses
forall (m :: * -> *). HasTezosClient m => m AliasesAndAddresses
Class.getAliasesAndAddresses
    pure $ Alias kind -> AliasesAndAddresses -> Maybe (KindedAddress kind)
forall (kind :: AddressKind).
Alias kind -> AliasesAndAddresses -> Maybe (KindedAddress kind)
lookupAddr Alias kind
alias AliasesAndAddresses
aas
      Maybe (KindedAddress kind)
-> (Maybe (KindedAddress kind)
    -> Either ResolveError (KindedAddress kind))
-> Either ResolveError (KindedAddress kind)
forall a b. a -> (a -> b) -> b
& ResolveError
-> Maybe (KindedAddress kind)
-> Either ResolveError (KindedAddress kind)
forall l r. l -> Maybe r -> Either l r
maybeToRight (AliasesAndAddresses -> ResolveError
handleMissing AliasesAndAddresses
aas)
    where
      handleMissing :: AliasesAndAddresses -> ResolveError
      handleMissing :: AliasesAndAddresses -> ResolveError
handleMissing AliasesAndAddresses
aas
        = ResolveError
-> (Address -> ResolveError) -> Maybe Address -> ResolveError
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text -> ResolveError
REAliasNotFound (Text -> ResolveError) -> Text -> ResolveError
forall a b. (a -> b) -> a -> b
$ AddressOrAlias kind -> Text
forall a b. (Buildable a, FromDoc b) => a -> b
pretty (AddressOrAlias kind -> Text) -> AddressOrAlias kind -> Text
forall a b. (a -> b) -> a -> b
$ Alias kind -> AddressOrAlias kind
forall (kind :: AddressKind). Alias kind -> AddressOrAlias kind
AddressAlias Alias kind
alias) (Alias kind -> Address -> ResolveError
forall (expectedKind :: AddressKind).
Alias expectedKind -> Address -> ResolveError
REWrongKind Alias kind
alias)
        (Maybe Address -> ResolveError) -> Maybe Address -> ResolveError
forall a b. (a -> b) -> a -> b
$ case Alias kind
alias of
            -- notice kind is flipped
            ImplicitAlias Text
aliasTxt -> KindedAddress 'AddressKindContract -> Address
forall {k} (c :: k -> Constraint) (f :: k -> *) (a :: k).
c a =>
f a -> Constrained c f
Constrained (KindedAddress 'AddressKindContract -> Address)
-> Maybe (KindedAddress 'AddressKindContract) -> Maybe Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Alias 'AddressKindContract
-> AliasesAndAddresses
-> Maybe (KindedAddress 'AddressKindContract)
forall (kind :: AddressKind).
Alias kind -> AliasesAndAddresses -> Maybe (KindedAddress kind)
lookupAddr (Text -> Alias 'AddressKindContract
ContractAlias Text
aliasTxt) AliasesAndAddresses
aas
            ContractAlias Text
aliasTxt -> KindedAddress 'AddressKindImplicit -> Address
forall {k} (c :: k -> Constraint) (f :: k -> *) (a :: k).
c a =>
f a -> Constrained c f
Constrained (KindedAddress 'AddressKindImplicit -> Address)
-> Maybe (KindedAddress 'AddressKindImplicit) -> Maybe Address
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Alias 'AddressKindImplicit
-> AliasesAndAddresses
-> Maybe (KindedAddress 'AddressKindImplicit)
forall (kind :: AddressKind).
Alias kind -> AliasesAndAddresses -> Maybe (KindedAddress kind)
lookupAddr (Text -> Alias 'AddressKindImplicit
ImplicitAlias Text
aliasTxt) AliasesAndAddresses
aas

  getAliasEither
    :: (Class.HasTezosClient m)
    => Alias kind -> m (Either ResolveError (Alias kind))
  getAliasEither :: forall (m :: * -> *).
HasTezosClient m =>
Alias kind -> m (Either ResolveError (Alias kind))
getAliasEither Alias kind
alias = (Either ResolveError (KindedAddress kind)
-> Alias kind -> Either ResolveError (Alias kind)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Alias kind
alias) (Either ResolveError (KindedAddress kind)
 -> Either ResolveError (Alias kind))
-> m (Either ResolveError (KindedAddress kind))
-> m (Either ResolveError (Alias kind))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Alias kind
-> m (Either ResolveError (ResolvedAddress (Alias kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
Alias kind
-> m (Either ResolveError (ResolvedAddress (Alias kind)))
resolveAddressEither Alias kind
alias -- check if alias exists

  resolveAddressWithAliasEither :: forall (m :: * -> *).
HasTezosClient m =>
Alias kind
-> m (Either ResolveError (ResolvedAddressAndAlias (Alias kind)))
resolveAddressWithAliasEither Alias kind
alias =
    (KindedAddress kind -> AddressWithAlias kind)
-> Either ResolveError (KindedAddress kind)
-> Either ResolveError (AddressWithAlias kind)
forall a b.
(a -> b) -> Either ResolveError a -> Either ResolveError b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (KindedAddress kind -> Alias kind -> AddressWithAlias kind
forall (kind :: AddressKind).
KindedAddress kind -> Alias kind -> AddressWithAlias kind
`AddressWithAlias` Alias kind
alias) (Either ResolveError (KindedAddress kind)
 -> Either ResolveError (AddressWithAlias kind))
-> m (Either ResolveError (KindedAddress kind))
-> m (Either ResolveError (AddressWithAlias kind))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Alias kind
-> m (Either ResolveError (ResolvedAddress (Alias kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
Alias kind
-> m (Either ResolveError (ResolvedAddress (Alias kind)))
resolveAddressEither Alias kind
alias

instance Resolve (AddressOrAlias kind) where
  type ResolvedAddress (AddressOrAlias kind) = KindedAddress kind
  type ResolvedAlias (AddressOrAlias kind) = Alias kind
  type ResolvedAddressAndAlias (AddressOrAlias kind) = AddressWithAlias kind

  resolveAddressEither
    :: (Class.HasTezosClient m)
    => AddressOrAlias kind -> m (Either ResolveError (KindedAddress kind))
  resolveAddressEither :: forall (m :: * -> *).
HasTezosClient m =>
AddressOrAlias kind -> m (Either ResolveError (KindedAddress kind))
resolveAddressEither = \case
    AddressResolved KindedAddress kind
addr -> KindedAddress kind
-> m (Either ResolveError (ResolvedAddress (KindedAddress kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
KindedAddress kind
-> m (Either ResolveError (ResolvedAddress (KindedAddress kind)))
resolveAddressEither KindedAddress kind
addr
    AddressAlias Alias kind
alias -> Alias kind
-> m (Either ResolveError (ResolvedAddress (Alias kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
Alias kind
-> m (Either ResolveError (ResolvedAddress (Alias kind)))
resolveAddressEither Alias kind
alias

  getAliasEither
    :: (Class.HasTezosClient m)
    => AddressOrAlias kind -> m (Either ResolveError (Alias kind))
  getAliasEither :: forall (m :: * -> *).
HasTezosClient m =>
AddressOrAlias kind -> m (Either ResolveError (Alias kind))
getAliasEither = \case
    AddressAlias Alias kind
alias -> Alias kind -> m (Either ResolveError (ResolvedAlias (Alias kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
Alias kind -> m (Either ResolveError (ResolvedAlias (Alias kind)))
getAliasEither Alias kind
alias
    AddressResolved KindedAddress kind
addr -> KindedAddress kind
-> m (Either ResolveError (ResolvedAlias (KindedAddress kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
KindedAddress kind
-> m (Either ResolveError (ResolvedAlias (KindedAddress kind)))
getAliasEither KindedAddress kind
addr

  resolveAddressWithAliasEither :: forall (m :: * -> *).
HasTezosClient m =>
AddressOrAlias kind
-> m (Either
        ResolveError (ResolvedAddressAndAlias (AddressOrAlias kind)))
resolveAddressWithAliasEither = \case
    AddressAlias Alias kind
alias -> Alias kind
-> m (Either ResolveError (ResolvedAddressAndAlias (Alias kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
Alias kind
-> m (Either ResolveError (ResolvedAddressAndAlias (Alias kind)))
resolveAddressWithAliasEither Alias kind
alias
    AddressResolved KindedAddress kind
addr -> KindedAddress kind
-> m (Either
        ResolveError (ResolvedAddressAndAlias (KindedAddress kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
KindedAddress kind
-> m (Either
        ResolveError (ResolvedAddressAndAlias (KindedAddress kind)))
resolveAddressWithAliasEither KindedAddress kind
addr

instance Resolve SomeAddressOrAlias where
  type ResolvedAddress SomeAddressOrAlias = L1Address
  type ResolvedAlias SomeAddressOrAlias = SomeAlias
  type ResolvedAddressAndAlias SomeAddressOrAlias = Constrained L1AddressKind AddressWithAlias

  resolveAddressEither
    :: (Class.HasTezosClient m)
    => SomeAddressOrAlias -> m (Either ResolveError L1Address)
  resolveAddressEither :: forall (m :: * -> *).
HasTezosClient m =>
SomeAddressOrAlias -> m (Either ResolveError L1Address)
resolveAddressEither = \case
    SAOAKindUnspecified Text
aliasText -> do
      AliasesAndAddresses
aas <- m AliasesAndAddresses
forall (m :: * -> *). HasTezosClient m => m AliasesAndAddresses
Class.getAliasesAndAddresses
      let addrs :: [L1Address]
addrs = (forall (a :: AddressKind).
 ConstrainAddressKind
   '[ 'AddressKindImplicit, 'AddressKindContract] a =>
 Alias a -> Maybe (KindedAddress a))
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     Alias
-> Maybe L1Address
forall {k} (m :: * -> *) (c :: k -> Constraint) (f :: k -> *)
       (g :: k -> *).
Functor m =>
(forall (a :: k). c a => f a -> m (g a))
-> Constrained c f -> m (Constrained c g)
traverseConstrained (Alias a -> AliasesAndAddresses -> Maybe (KindedAddress a)
forall (kind :: AddressKind).
Alias kind -> AliasesAndAddresses -> Maybe (KindedAddress kind)
`lookupAddr` AliasesAndAddresses
aas) (Constrained
   (ConstrainAddressKind
      '[ 'AddressKindImplicit, 'AddressKindContract])
   Alias
 -> Maybe L1Address)
-> [Constrained
      (ConstrainAddressKind
         '[ 'AddressKindImplicit, 'AddressKindContract])
      Alias]
-> [L1Address]
forall a b. (a -> Maybe b) -> [a] -> [b]
`mapMaybe`
            [ Alias 'AddressKindContract
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     Alias
forall {k} (c :: k -> Constraint) (f :: k -> *) (a :: k).
c a =>
f a -> Constrained c f
Constrained (Alias 'AddressKindContract
 -> Constrained
      (ConstrainAddressKind
         '[ 'AddressKindImplicit, 'AddressKindContract])
      Alias)
-> Alias 'AddressKindContract
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     Alias
forall a b. (a -> b) -> a -> b
$ forall (kind :: AddressKind).
(SingI kind, L1AddressKind kind) =>
Text -> Alias kind
mkAlias @'AddressKindContract Text
aliasText
            , Alias 'AddressKindImplicit
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     Alias
forall {k} (c :: k -> Constraint) (f :: k -> *) (a :: k).
c a =>
f a -> Constrained c f
Constrained (Alias 'AddressKindImplicit
 -> Constrained
      (ConstrainAddressKind
         '[ 'AddressKindImplicit, 'AddressKindContract])
      Alias)
-> Alias 'AddressKindImplicit
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     Alias
forall a b. (a -> b) -> a -> b
$ forall (kind :: AddressKind).
(SingI kind, L1AddressKind kind) =>
Text -> Alias kind
mkAlias @'AddressKindImplicit Text
aliasText
            ]
      Either ResolveError L1Address -> m (Either ResolveError L1Address)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ResolveError L1Address
 -> m (Either ResolveError L1Address))
-> Either ResolveError L1Address
-> m (Either ResolveError L1Address)
forall a b. (a -> b) -> a -> b
$ case [L1Address]
addrs of
        [] -> ResolveError -> Either ResolveError L1Address
forall a b. a -> Either a b
Left (ResolveError -> Either ResolveError L1Address)
-> ResolveError -> Either ResolveError L1Address
forall a b. (a -> b) -> a -> b
$ Text -> ResolveError
REAliasNotFound Text
aliasText
        [L1Address
addr] -> L1Address -> Either ResolveError L1Address
forall a b. b -> Either a b
Right L1Address
addr
        [L1Address]
as -> ResolveError -> Either ResolveError L1Address
forall a b. a -> Either a b
Left (ResolveError -> Either ResolveError L1Address)
-> ResolveError -> Either ResolveError L1Address
forall a b. (a -> b) -> a -> b
$ Text -> [L1Address] -> ResolveError
REAmbiguousAlias Text
aliasText [L1Address]
as
    SAOAKindSpecified AddressOrAlias kind
aoa ->
      (KindedAddress kind -> L1Address)
-> Either ResolveError (KindedAddress kind)
-> Either ResolveError L1Address
forall a b.
(a -> b) -> Either ResolveError a -> Either ResolveError b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap KindedAddress kind -> L1Address
forall {k} (c :: k -> Constraint) (f :: k -> *) (a :: k).
c a =>
f a -> Constrained c f
Constrained (Either ResolveError (KindedAddress kind)
 -> Either ResolveError L1Address)
-> m (Either ResolveError (KindedAddress kind))
-> m (Either ResolveError L1Address)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AddressOrAlias kind
-> m (Either ResolveError (ResolvedAddress (AddressOrAlias kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
AddressOrAlias kind
-> m (Either ResolveError (ResolvedAddress (AddressOrAlias kind)))
resolveAddressEither AddressOrAlias kind
aoa ((L1AddressKind kind, SingI kind) =>
 m (Either ResolveError L1Address))
-> Dict (L1AddressKind kind, SingI kind)
-> m (Either ResolveError L1Address)
forall (c :: Constraint) e r. HasDict c e => (c => r) -> e -> r
\\ AddressOrAlias kind -> Dict (L1AddressKind kind, SingI kind)
forall (kind :: AddressKind).
AddressOrAlias kind -> Dict (L1AddressKind kind, SingI kind)
addressOrAliasKindSanity AddressOrAlias kind
aoa

  getAliasEither
    :: (Class.HasTezosClient m)
    => SomeAddressOrAlias -> m (Either ResolveError SomeAlias)
  getAliasEither :: forall (m :: * -> *).
HasTezosClient m =>
SomeAddressOrAlias -> m (Either ResolveError SomeAlias)
getAliasEither = \case
    SAOAKindSpecified AddressOrAlias kind
aoa -> do
      (Alias kind -> SomeAlias)
-> Either ResolveError (Alias kind)
-> Either ResolveError SomeAlias
forall a b.
(a -> b) -> Either ResolveError a -> Either ResolveError b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Alias kind -> SomeAlias
forall (a :: AddressKind). Alias a -> SomeAlias
SomeAlias
        (Either ResolveError (Alias kind) -> Either ResolveError SomeAlias)
-> m (Either ResolveError (Alias kind))
-> m (Either ResolveError SomeAlias)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AddressOrAlias kind
-> m (Either ResolveError (ResolvedAlias (AddressOrAlias kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
AddressOrAlias kind
-> m (Either ResolveError (ResolvedAlias (AddressOrAlias kind)))
getAliasEither AddressOrAlias kind
aoa ((L1AddressKind kind, SingI kind) =>
 m (Either ResolveError SomeAlias))
-> Dict (L1AddressKind kind, SingI kind)
-> m (Either ResolveError SomeAlias)
forall (c :: Constraint) e r. HasDict c e => (c => r) -> e -> r
\\ AddressOrAlias kind -> Dict (L1AddressKind kind, SingI kind)
forall (kind :: AddressKind).
AddressOrAlias kind -> Dict (L1AddressKind kind, SingI kind)
addressOrAliasKindSanity AddressOrAlias kind
aoa
    aoa :: SomeAddressOrAlias
aoa@SAOAKindUnspecified{} -> ExceptT ResolveError m SomeAlias
-> m (Either ResolveError SomeAlias)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT do
      -- Find out whether this alias is associated with an implicit address or a contract,
      -- and return an @Alias kind@ of the correct kind.
      m (Either
     ResolveError
     (Constrained
        (ConstrainAddressKind
           '[ 'AddressKindImplicit, 'AddressKindContract])
        AddressWithAlias))
-> ExceptT
     ResolveError
     m
     (Constrained
        (ConstrainAddressKind
           '[ 'AddressKindImplicit, 'AddressKindContract])
        AddressWithAlias)
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (SomeAddressOrAlias
-> m (Either
        ResolveError (ResolvedAddressAndAlias SomeAddressOrAlias))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
SomeAddressOrAlias
-> m (Either
        ResolveError (ResolvedAddressAndAlias SomeAddressOrAlias))
resolveAddressWithAliasEither SomeAddressOrAlias
aoa) ExceptT
  ResolveError
  m
  (Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     AddressWithAlias)
-> (Constrained
      (ConstrainAddressKind
         '[ 'AddressKindImplicit, 'AddressKindContract])
      AddressWithAlias
    -> SomeAlias)
-> ExceptT ResolveError m SomeAlias
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (forall (t :: AddressKind).
 L1AddressKind t =>
 AddressWithAlias t -> SomeAlias)
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     AddressWithAlias
-> SomeAlias
forall {k} (c :: k -> Constraint) (f :: k -> *) r.
(forall (t :: k). c t => f t -> r) -> Constrained c f -> r
foldConstrained (Alias t -> SomeAlias
forall (a :: AddressKind). Alias a -> SomeAlias
SomeAlias (Alias t -> SomeAlias)
-> (AddressWithAlias t -> Alias t)
-> AddressWithAlias t
-> SomeAlias
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AddressWithAlias t -> Alias t
forall (kind :: AddressKind). AddressWithAlias kind -> Alias kind
awaAlias)

  resolveAddressWithAliasEither :: forall (m :: * -> *).
HasTezosClient m =>
SomeAddressOrAlias
-> m (Either
        ResolveError (ResolvedAddressAndAlias SomeAddressOrAlias))
resolveAddressWithAliasEither SomeAddressOrAlias
addr = ExceptT
  ResolveError
  m
  (Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     AddressWithAlias)
-> m (Either
        ResolveError
        (Constrained
           (ConstrainAddressKind
              '[ 'AddressKindImplicit, 'AddressKindContract])
           AddressWithAlias))
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT case SomeAddressOrAlias
addr of
    SAOAKindSpecified AddressOrAlias kind
aoa -> do
      KindedAddress kind
kaddr <- m (Either ResolveError (KindedAddress kind))
-> ExceptT ResolveError m (KindedAddress kind)
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either ResolveError (KindedAddress kind))
 -> ExceptT ResolveError m (KindedAddress kind))
-> m (Either ResolveError (KindedAddress kind))
-> ExceptT ResolveError m (KindedAddress kind)
forall a b. (a -> b) -> a -> b
$ AddressOrAlias kind
-> m (Either ResolveError (ResolvedAddress (AddressOrAlias kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
AddressOrAlias kind
-> m (Either ResolveError (ResolvedAddress (AddressOrAlias kind)))
resolveAddressEither AddressOrAlias kind
aoa
      Alias kind
kalias <- m (Either ResolveError (Alias kind))
-> ExceptT ResolveError m (Alias kind)
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either ResolveError (Alias kind))
 -> ExceptT ResolveError m (Alias kind))
-> m (Either ResolveError (Alias kind))
-> ExceptT ResolveError m (Alias kind)
forall a b. (a -> b) -> a -> b
$ AddressOrAlias kind
-> m (Either ResolveError (ResolvedAlias (AddressOrAlias kind)))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
AddressOrAlias kind
-> m (Either ResolveError (ResolvedAlias (AddressOrAlias kind)))
getAliasEither AddressOrAlias kind
aoa
      pure $ AddressWithAlias kind
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     AddressWithAlias
forall {k} (c :: k -> Constraint) (f :: k -> *) (a :: k).
c a =>
f a -> Constrained c f
Constrained (KindedAddress kind -> Alias kind -> AddressWithAlias kind
forall (kind :: AddressKind).
KindedAddress kind -> Alias kind -> AddressWithAlias kind
AddressWithAlias KindedAddress kind
kaddr Alias kind
kalias) ((L1AddressKind kind, SingI kind) =>
 Constrained
   (ConstrainAddressKind
      '[ 'AddressKindImplicit, 'AddressKindContract])
   AddressWithAlias)
-> Dict (L1AddressKind kind, SingI kind)
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     AddressWithAlias
forall (c :: Constraint) e r. HasDict c e => (c => r) -> e -> r
\\ AddressOrAlias kind -> Dict (L1AddressKind kind, SingI kind)
forall (kind :: AddressKind).
AddressOrAlias kind -> Dict (L1AddressKind kind, SingI kind)
addressOrAliasKindSanity AddressOrAlias kind
aoa
    aoa :: SomeAddressOrAlias
aoa@(SAOAKindUnspecified Text
aliasText) -> do
      m (Either ResolveError L1Address)
-> ExceptT ResolveError m L1Address
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT (SomeAddressOrAlias
-> m (Either ResolveError (ResolvedAddress SomeAddressOrAlias))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
SomeAddressOrAlias
-> m (Either ResolveError (ResolvedAddress SomeAddressOrAlias))
resolveAddressEither SomeAddressOrAlias
aoa) ExceptT ResolveError m L1Address
-> (L1Address
    -> Constrained
         (ConstrainAddressKind
            '[ 'AddressKindImplicit, 'AddressKindContract])
         AddressWithAlias)
-> ExceptT
     ResolveError
     m
     (Constrained
        (ConstrainAddressKind
           '[ 'AddressKindImplicit, 'AddressKindContract])
        AddressWithAlias)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> (forall (t :: AddressKind).
 L1AddressKind t =>
 KindedAddress t
 -> Constrained
      (ConstrainAddressKind
         '[ 'AddressKindImplicit, 'AddressKindContract])
      AddressWithAlias)
-> L1Address
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     AddressWithAlias
forall {k} (c :: k -> Constraint) (f :: k -> *) r.
(forall (t :: k). c t => f t -> r) -> Constrained c f -> r
foldConstrained
        \KindedAddress t
kaddr -> AddressWithAlias t
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     AddressWithAlias
forall {k} (c :: k -> Constraint) (f :: k -> *) (a :: k).
c a =>
f a -> Constrained c f
Constrained (AddressWithAlias t
 -> Constrained
      (ConstrainAddressKind
         '[ 'AddressKindImplicit, 'AddressKindContract])
      AddressWithAlias)
-> AddressWithAlias t
-> Constrained
     (ConstrainAddressKind
        '[ 'AddressKindImplicit, 'AddressKindContract])
     AddressWithAlias
forall a b. (a -> b) -> a -> b
$ KindedAddress t -> Alias t -> AddressWithAlias t
forall (kind :: AddressKind).
KindedAddress kind -> Alias kind -> AddressWithAlias kind
AddressWithAlias KindedAddress t
kaddr (Alias t -> AddressWithAlias t) -> Alias t -> AddressWithAlias t
forall a b. (a -> b) -> a -> b
$ Text -> Alias t
forall (kind :: AddressKind).
(SingI kind, L1AddressKind kind) =>
Text -> Alias kind
mkAlias Text
aliasText (SingI t => Alias t) -> Dict (SingI t) -> Alias t
forall (c :: Constraint) e r. HasDict c e => (c => r) -> e -> r
\\ KindedAddress t -> Dict (SingI t)
forall (kind :: AddressKind).
KindedAddress kind -> Dict (SingI kind)
addressKindSanity KindedAddress t
kaddr

-- | Looks up the address and alias with the given @addressOrAlias@.
resolveAddressWithAlias
  :: forall addressOrAlias m
   . (Class.HasTezosClient m, MonadThrow m,Resolve addressOrAlias)
  => addressOrAlias
  -> m (ResolvedAddressAndAlias addressOrAlias)
resolveAddressWithAlias :: forall addressOrAlias (m :: * -> *).
(HasTezosClient m, MonadThrow m, Resolve addressOrAlias) =>
addressOrAlias -> m (ResolvedAddressAndAlias addressOrAlias)
resolveAddressWithAlias = addressOrAlias
-> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
resolveAddressWithAliasEither (addressOrAlias
 -> m (Either
         ResolveError (ResolvedAddressAndAlias addressOrAlias)))
-> (Either ResolveError (ResolvedAddressAndAlias addressOrAlias)
    -> m (ResolvedAddressAndAlias addressOrAlias))
-> addressOrAlias
-> m (ResolvedAddressAndAlias addressOrAlias)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (ResolveError -> m (ResolvedAddressAndAlias addressOrAlias))
-> (ResolvedAddressAndAlias addressOrAlias
    -> m (ResolvedAddressAndAlias addressOrAlias))
-> Either ResolveError (ResolvedAddressAndAlias addressOrAlias)
-> m (ResolvedAddressAndAlias addressOrAlias)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (TezosClientError -> m (ResolvedAddressAndAlias addressOrAlias)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (TezosClientError -> m (ResolvedAddressAndAlias addressOrAlias))
-> (ResolveError -> TezosClientError)
-> ResolveError
-> m (ResolvedAddressAndAlias addressOrAlias)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResolveError -> TezosClientError
ResolveError) ResolvedAddressAndAlias addressOrAlias
-> m (ResolvedAddressAndAlias addressOrAlias)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

-- | Looks up the address and alias with the given @addressOrAlias@.
resolveAddressWithAliasMaybe
  :: forall addressOrAlias m
   . (Class.HasTezosClient m, Resolve addressOrAlias)
  => addressOrAlias
  -> m (Maybe (ResolvedAddressAndAlias addressOrAlias))
resolveAddressWithAliasMaybe :: forall addressOrAlias (m :: * -> *).
(HasTezosClient m, Resolve addressOrAlias) =>
addressOrAlias
-> m (Maybe (ResolvedAddressAndAlias addressOrAlias))
resolveAddressWithAliasMaybe = (Either ResolveError (ResolvedAddressAndAlias addressOrAlias)
 -> Maybe (ResolvedAddressAndAlias addressOrAlias))
-> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
-> m (Maybe (ResolvedAddressAndAlias addressOrAlias))
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either ResolveError (ResolvedAddressAndAlias addressOrAlias)
-> Maybe (ResolvedAddressAndAlias addressOrAlias)
forall l r. Either l r -> Maybe r
rightToMaybe (m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
 -> m (Maybe (ResolvedAddressAndAlias addressOrAlias)))
-> (addressOrAlias
    -> m (Either
            ResolveError (ResolvedAddressAndAlias addressOrAlias)))
-> addressOrAlias
-> m (Maybe (ResolvedAddressAndAlias addressOrAlias))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. addressOrAlias
-> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddressAndAlias addressOrAlias))
resolveAddressWithAliasEither

-- | Looks up the address associated with the given @addressOrAlias@.
--
-- Will throw a 'TezosClientError' if @addressOrAlias@ is an alias and:
--
-- * the alias does not exist.
-- * the alias exists but its address is of the wrong kind.
--
-- When the alias is associated with __both__ an implicit and a contract address:
--
-- * The 'SomeAddressOrAlias' instance will throw a 'TezosClientError',
--   unless the alias is prefixed with @implicit:@ or @contract:@ to disambiguate.
-- * The 'AddressOrAlias' instance will return the address with the requested kind.
resolveAddress
  :: forall addressOrAlias m
   . (Class.HasTezosClient m, MonadThrow m, Resolve addressOrAlias)
  => addressOrAlias
  -> m (ResolvedAddress addressOrAlias)
resolveAddress :: forall addressOrAlias (m :: * -> *).
(HasTezosClient m, MonadThrow m, Resolve addressOrAlias) =>
addressOrAlias -> m (ResolvedAddress addressOrAlias)
resolveAddress = addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
resolveAddressEither (addressOrAlias
 -> m (Either ResolveError (ResolvedAddress addressOrAlias)))
-> (Either ResolveError (ResolvedAddress addressOrAlias)
    -> m (ResolvedAddress addressOrAlias))
-> addressOrAlias
-> m (ResolvedAddress addressOrAlias)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (ResolveError -> m (ResolvedAddress addressOrAlias))
-> (ResolvedAddress addressOrAlias
    -> m (ResolvedAddress addressOrAlias))
-> Either ResolveError (ResolvedAddress addressOrAlias)
-> m (ResolvedAddress addressOrAlias)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (TezosClientError -> m (ResolvedAddress addressOrAlias)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (TezosClientError -> m (ResolvedAddress addressOrAlias))
-> (ResolveError -> TezosClientError)
-> ResolveError
-> m (ResolvedAddress addressOrAlias)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResolveError -> TezosClientError
ResolveError) ResolvedAddress addressOrAlias
-> m (ResolvedAddress addressOrAlias)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

-- | Looks up the address associated with the given @addressOrAlias@.
--
-- Will return 'Nothing' if @addressOrAlias@ is an alias and:
--
-- * the alias does not exist.
-- * the alias exists but its address is of the wrong kind.
--
-- When the alias is associated with __both__ an implicit and a contract address:
--
-- * The 'SomeAddressOrAlias' instance will throw a 'TezosClientError',
--   unless the alias is prefixed with @implicit:@ or @contract:@ to disambiguate.
-- * The 'AddressOrAlias' instance will return the address with the requested kind.
resolveAddressMaybe
  :: forall addressOrAlias m
   . (Class.HasTezosClient m, MonadThrow m, Resolve addressOrAlias)
  => addressOrAlias
  -> m (Maybe (ResolvedAddress addressOrAlias))
resolveAddressMaybe :: forall addressOrAlias (m :: * -> *).
(HasTezosClient m, MonadThrow m, Resolve addressOrAlias) =>
addressOrAlias -> m (Maybe (ResolvedAddress addressOrAlias))
resolveAddressMaybe addressOrAlias
aoa = addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
addressOrAlias
-> m (Either ResolveError (ResolvedAddress addressOrAlias))
resolveAddressEither addressOrAlias
aoa m (Either ResolveError (ResolvedAddress addressOrAlias))
-> (Either ResolveError (ResolvedAddress addressOrAlias)
    -> m (Maybe (ResolvedAddress addressOrAlias)))
-> m (Maybe (ResolvedAddress addressOrAlias))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ResolveError -> m (Maybe (ResolvedAddress addressOrAlias)))
-> (ResolvedAddress addressOrAlias
    -> m (Maybe (ResolvedAddress addressOrAlias)))
-> Either ResolveError (ResolvedAddress addressOrAlias)
-> m (Maybe (ResolvedAddress addressOrAlias))
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ResolveError -> m (Maybe (ResolvedAddress addressOrAlias))
forall (m :: * -> *) a. MonadThrow m => ResolveError -> m (Maybe a)
handleResolveError (Maybe (ResolvedAddress addressOrAlias)
-> m (Maybe (ResolvedAddress addressOrAlias))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (ResolvedAddress addressOrAlias)
 -> m (Maybe (ResolvedAddress addressOrAlias)))
-> (ResolvedAddress addressOrAlias
    -> Maybe (ResolvedAddress addressOrAlias))
-> ResolvedAddress addressOrAlias
-> m (Maybe (ResolvedAddress addressOrAlias))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResolvedAddress addressOrAlias
-> Maybe (ResolvedAddress addressOrAlias)
forall a. a -> Maybe a
Just)

handleResolveError :: MonadThrow m => ResolveError -> m (Maybe a)
handleResolveError :: forall (m :: * -> *) a. MonadThrow m => ResolveError -> m (Maybe a)
handleResolveError = \case
  e :: ResolveError
e@REAmbiguousAlias{} -> TezosClientError -> m (Maybe a)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (TezosClientError -> m (Maybe a))
-> TezosClientError -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ ResolveError -> TezosClientError
ResolveError ResolveError
e
  REAliasNotFound{} -> Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
  REAddressNotFound{} -> Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
  REWrongKind{} -> Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing

{- | Looks up the alias associated with the given @addressOrAlias@.

Will throw a 'TezosClientError' if @addressOrAlias@:

  * is an address that is not associated with any alias.
  * is an alias that does not exist.
  * is an alias that exists but its address is of the wrong kind.

When the alias is associated with __both__ an implicit and a contract address:

  * The 'SomeAddressOrAlias' instance will throw a 'TezosClientError',
    unless the alias is prefixed with @implicit:@ or @contract:@ to disambiguate.
  * The 'AddressOrAlias' instance will return the alias.
-}
getAlias
  :: forall addressOrAlias m
   . (Class.HasTezosClient m, MonadThrow m, Resolve addressOrAlias)
  => addressOrAlias
  -> m (ResolvedAlias addressOrAlias)
getAlias :: forall addressOrAlias (m :: * -> *).
(HasTezosClient m, MonadThrow m, Resolve addressOrAlias) =>
addressOrAlias -> m (ResolvedAlias addressOrAlias)
getAlias = addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
getAliasEither (addressOrAlias
 -> m (Either ResolveError (ResolvedAlias addressOrAlias)))
-> (Either ResolveError (ResolvedAlias addressOrAlias)
    -> m (ResolvedAlias addressOrAlias))
-> addressOrAlias
-> m (ResolvedAlias addressOrAlias)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (ResolveError -> m (ResolvedAlias addressOrAlias))
-> (ResolvedAlias addressOrAlias
    -> m (ResolvedAlias addressOrAlias))
-> Either ResolveError (ResolvedAlias addressOrAlias)
-> m (ResolvedAlias addressOrAlias)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (TezosClientError -> m (ResolvedAlias addressOrAlias)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (TezosClientError -> m (ResolvedAlias addressOrAlias))
-> (ResolveError -> TezosClientError)
-> ResolveError
-> m (ResolvedAlias addressOrAlias)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResolveError -> TezosClientError
ResolveError) ResolvedAlias addressOrAlias -> m (ResolvedAlias addressOrAlias)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

{- | Looks up the alias associated with the given @addressOrAlias@.

Will return 'Nothing' if @addressOrAlias@:

  * is an address that is not associated with any alias.
  * is an alias that does not exist.
  * is an alias that exists but its address is of the wrong kind.

When the alias is associated with __both__ an implicit and a contract address:

  * The 'SomeAddressOrAlias' instance will throw a 'TezosClientError',
    unless the alias is prefixed with @implicit:@ or @contract:@ to disambiguate.
  * The 'AddressOrAlias' instance will return the alias.
-}
getAliasMaybe
  :: forall addressOrAlias m
   . (Class.HasTezosClient m, MonadThrow m, Resolve addressOrAlias)
  => addressOrAlias
  -> m (Maybe (ResolvedAlias addressOrAlias))
getAliasMaybe :: forall addressOrAlias (m :: * -> *).
(HasTezosClient m, MonadThrow m, Resolve addressOrAlias) =>
addressOrAlias -> m (Maybe (ResolvedAlias addressOrAlias))
getAliasMaybe addressOrAlias
aoa = addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
forall addressOrAlias (m :: * -> *).
(Resolve addressOrAlias, HasTezosClient m) =>
addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
forall (m :: * -> *).
HasTezosClient m =>
addressOrAlias
-> m (Either ResolveError (ResolvedAlias addressOrAlias))
getAliasEither addressOrAlias
aoa m (Either ResolveError (ResolvedAlias addressOrAlias))
-> (Either ResolveError (ResolvedAlias addressOrAlias)
    -> m (Maybe (ResolvedAlias addressOrAlias)))
-> m (Maybe (ResolvedAlias addressOrAlias))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ResolveError -> m (Maybe (ResolvedAlias addressOrAlias)))
-> (ResolvedAlias addressOrAlias
    -> m (Maybe (ResolvedAlias addressOrAlias)))
-> Either ResolveError (ResolvedAlias addressOrAlias)
-> m (Maybe (ResolvedAlias addressOrAlias))
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ResolveError -> m (Maybe (ResolvedAlias addressOrAlias))
forall (m :: * -> *) a. MonadThrow m => ResolveError -> m (Maybe a)
handleResolveError (Maybe (ResolvedAlias addressOrAlias)
-> m (Maybe (ResolvedAlias addressOrAlias))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (ResolvedAlias addressOrAlias)
 -> m (Maybe (ResolvedAlias addressOrAlias)))
-> (ResolvedAlias addressOrAlias
    -> Maybe (ResolvedAlias addressOrAlias))
-> ResolvedAlias addressOrAlias
-> m (Maybe (ResolvedAlias addressOrAlias))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResolvedAlias addressOrAlias
-> Maybe (ResolvedAlias addressOrAlias)
forall a. a -> Maybe a
Just)