-- SPDX-FileCopyrightText: 2022 Oxhead Alpha -- SPDX-License-Identifier: LicenseRef-MIT-OA module Morley.Client.Action.Delegation ( setDelegateOp , registerDelegateOp ) where import Colog.Core.Class (HasLog) import Colog.Message (Message) import Morley.Client.Action.Common import Morley.Client.Action.Operation import Morley.Client.RPC.Class import Morley.Client.RPC.Types import Morley.Client.TezosClient.Class import Morley.Client.Types import Morley.Tezos.Address import Morley.Tezos.Crypto -- | Set or revoke a delegate for the sender. -- To set a supply @Just delegate@ as the second argument. -- To withdraw a delegate supply @Nothing@ as the second argument. -- -- Some notes on delegations: -- -- Implicit Accounts can either be /registered delegates/, have no delegate, -- or have a delegate set without being /registered delegates/ themselves. -- -- For example imagine two implicit addresses Alice and Bob: -- * Alice registers as delegate using `registerDelegateOp`. This means that Alice delegates to Alice. -- * Bob sets Alice as his delegate. This delegates Bob's staking rights to Alice. -- -- Now, Alice can't change their delegate, because that would revoke Alice as delegate and make -- Bob's delegation void. So @setDelegateOp alice Nothing@ would throw a @FailedUnDelegation alice@ exception. -- -- However, Bob, not beeing a /registered delegate/ can: -- * Revoke the delegation to alice @setDelegateOp bob Nothing@ -- * Delegate to another "registered delegate": @registerDelegateOp charly >> setDelegateOp bob charly@ -- * Become a registered delegate himself: @registerDelegateOp bob@ -- -- Smart Contracts can also delegate to /registered delegates/, but can't be /registered delegates/ themselves. -- setDelegateOp :: ( HasTezosRpc m , HasTezosClient m , MonadReader env m , HasLog env Message m) => ImplicitAddressWithAlias -> Maybe KeyHash -> m OperationHash setDelegateOp sender delegate = fmap fst . runOperationsNonEmpty sender . one . OpDelegation $ DelegationData delegate Nothing -- | Register the sender as its delegate and become a "registered delegate" -- Alias for @setDelegateOp sender (Just sender)@ registerDelegateOp :: ( HasTezosRpc m , HasTezosClient m , MonadReader env m , HasLog env Message m) => ImplicitAddressWithAlias -> m OperationHash registerDelegateOp sender = do let senderKh = unImplicitAddress $ awaAddress sender setDelegateOp sender (Just senderKh)