morley-client-0.3.1: src/Morley/Client/Action/Delegation.hs
-- 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)