module Morley.Client.Action.Operation
( Result
, runOperations
, runOperationsNonEmpty
, dryRunOperationsNonEmpty
) where
import Control.Lens (has, (%=), (&~))
import Data.List (zipWith4)
import Data.List.NonEmpty qualified as NE
import Data.Singletons (Sing, SingI, sing)
import Data.Text qualified as T
import Fmt (blockListF', listF, pretty, (+|), (|+))
import Morley.Client.Action.Common
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
import Morley.Client.Types
import Morley.Micheline (StringEncode(..), TezosInt64, TezosMutez(..))
import Morley.Tezos.Address
import Morley.Tezos.Crypto
import Morley.Util.ByteString
data Result
instance OperationInfoDescriptor Result where
type TransferInfo Result = ()
type OriginationInfo Result = Address
type RevealInfo Result = ()
logOperations
:: forall (runMode :: RunMode) env m.
( WithClientLog env m
, HasTezosClient m
, SingI runMode
)
=> AddressOrAlias
-> NonEmpty (OperationInfo ClientInput)
-> m ()
logOperations :: AddressOrAlias -> NonEmpty (OperationInfo ClientInput) -> m ()
logOperations AddressOrAlias
sender NonEmpty (OperationInfo ClientInput)
ops = do
let runMode :: Sing runMode
runMode = SingI runMode => Sing runMode
forall k (a :: k). SingI a => Sing a
sing @runMode
opName :: Builder
opName =
if | (Element (NonEmpty (OperationInfo ClientInput)) -> Bool)
-> NonEmpty (OperationInfo ClientInput) -> Bool
forall t. Container t => (Element t -> Bool) -> t -> Bool
all (Getting Any (OperationInfo ClientInput) TransactionData
-> OperationInfo ClientInput -> Bool
forall s a. Getting Any s a -> s -> Bool
has Getting Any (OperationInfo ClientInput) TransactionData
forall i. Prism' (OperationInfo i) (TransferInfo i)
_OpTransfer) NonEmpty (OperationInfo ClientInput)
ops -> Builder
"transactions"
| (Element (NonEmpty (OperationInfo ClientInput)) -> Bool)
-> NonEmpty (OperationInfo ClientInput) -> Bool
forall t. Container t => (Element t -> Bool) -> t -> Bool
all (Getting Any (OperationInfo ClientInput) OriginationData
-> OperationInfo ClientInput -> Bool
forall s a. Getting Any s a -> s -> Bool
has Getting Any (OperationInfo ClientInput) OriginationData
forall i. Prism' (OperationInfo i) (OriginationInfo i)
_OpOriginate) NonEmpty (OperationInfo ClientInput)
ops -> Builder
"originations"
| (Element (NonEmpty (OperationInfo ClientInput)) -> Bool)
-> NonEmpty (OperationInfo ClientInput) -> Bool
forall t. Container t => (Element t -> Bool) -> t -> Bool
all (Getting Any (OperationInfo ClientInput) RevealData
-> OperationInfo ClientInput -> Bool
forall s a. Getting Any s a -> s -> Bool
has Getting Any (OperationInfo ClientInput) RevealData
forall i. Prism' (OperationInfo i) (RevealInfo i)
_OpReveal) NonEmpty (OperationInfo ClientInput)
ops -> Builder
"reveals"
| Bool
otherwise -> Builder
"operations"
buildOp :: (OperationInfo ClientInput, Maybe Alias) -> Builder
buildOp = \case
(OpTransfer TransferInfo ClientInput
tx, Maybe Alias
mbAlias) ->
Maybe Alias -> TransactionData -> Builder
buildTxDataWithAlias Maybe Alias
mbAlias TransferInfo ClientInput
TransactionData
tx
(OpOriginate OriginationInfo ClientInput
orig, Maybe Alias
_) ->
OriginationData -> AliasHint
odName OriginationInfo ClientInput
OriginationData
orig AliasHint -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+ Builder
" (temporary alias)"
(OpReveal RevealInfo ClientInput
rv, Maybe Alias
mbAlias) ->
Builder
"Key " Builder -> Builder -> Builder
forall b. FromBuilder b => Builder -> Builder -> b
+| RevealData -> PublicKey
rdPublicKey RevealInfo ClientInput
RevealData
rv PublicKey -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+ Builder -> (Alias -> Builder) -> Maybe Alias -> Builder
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Builder
"" (\Alias
a -> Builder
" (" Builder -> Builder -> Builder
forall b. FromBuilder b => Builder -> Builder -> b
+| Alias
a Alias -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+ Builder
")") Maybe Alias
mbAlias
AddressOrAlias
sender' <- case AddressOrAlias
sender of
addr :: AddressOrAlias
addr@AddressResolved{} -> case Sing runMode
runMode of
Sing runMode
SRealRun -> Alias -> AddressOrAlias
AddressAlias (Alias -> AddressOrAlias) -> m Alias -> m AddressOrAlias
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AddressOrAlias -> m Alias
forall (m :: * -> *). HasTezosClient m => AddressOrAlias -> m Alias
getAlias AddressOrAlias
sender
Sing runMode
SDryRun -> AddressOrAlias -> m AddressOrAlias
forall (f :: * -> *) a. Applicative f => a -> f a
pure AddressOrAlias
addr
AddressOrAlias
alias -> AddressOrAlias -> m AddressOrAlias
forall (f :: * -> *) a. Applicative f => a -> f a
pure AddressOrAlias
alias
NonEmpty (Maybe Alias)
aliases <- case Sing runMode
runMode of
Sing runMode
SRealRun ->
NonEmpty (OperationInfo ClientInput)
-> (OperationInfo ClientInput -> m (Maybe Alias))
-> m (NonEmpty (Maybe Alias))
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM NonEmpty (OperationInfo ClientInput)
ops ((OperationInfo ClientInput -> m (Maybe Alias))
-> m (NonEmpty (Maybe Alias)))
-> (OperationInfo ClientInput -> m (Maybe Alias))
-> m (NonEmpty (Maybe Alias))
forall a b. (a -> b) -> a -> b
$ \case
OpTransfer (TransactionData tx) ->
Alias -> Maybe Alias
forall a. a -> Maybe a
Just (Alias -> Maybe Alias) -> m Alias -> m (Maybe Alias)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (AddressOrAlias -> m Alias
forall (m :: * -> *). HasTezosClient m => AddressOrAlias -> m Alias
getAlias (AddressOrAlias -> m Alias)
-> (Address -> AddressOrAlias) -> Address -> m Alias
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address -> AddressOrAlias
AddressResolved (Address -> m Alias) -> Address -> m Alias
forall a b. (a -> b) -> a -> b
$ TD (Value t) -> Address
forall t. TD t -> Address
tdReceiver TD (Value t)
tx)
OpOriginate OriginationInfo ClientInput
_ ->
Maybe Alias -> m (Maybe Alias)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Alias
forall a. Maybe a
Nothing
OpReveal RevealInfo ClientInput
r ->
Alias -> Maybe Alias
forall a. a -> Maybe a
Just (Alias -> Maybe Alias) -> m Alias -> m (Maybe Alias)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (AddressOrAlias -> m Alias
forall (m :: * -> *). HasTezosClient m => AddressOrAlias -> m Alias
getAlias (AddressOrAlias -> m Alias)
-> (PublicKey -> AddressOrAlias) -> PublicKey -> m Alias
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Address -> AddressOrAlias
AddressResolved (Address -> AddressOrAlias)
-> (PublicKey -> Address) -> PublicKey -> AddressOrAlias
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicKey -> Address
mkKeyAddress (PublicKey -> m Alias) -> PublicKey -> m Alias
forall a b. (a -> b) -> a -> b
$ RevealData -> PublicKey
rdPublicKey RevealInfo ClientInput
RevealData
r)
Sing runMode
SDryRun -> NonEmpty (Maybe Alias) -> m (NonEmpty (Maybe Alias))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NonEmpty (Maybe Alias) -> m (NonEmpty (Maybe Alias)))
-> NonEmpty (Maybe Alias) -> m (NonEmpty (Maybe Alias))
forall a b. (a -> b) -> a -> b
$ NonEmpty (OperationInfo ClientInput)
ops NonEmpty (OperationInfo ClientInput)
-> Maybe Alias -> NonEmpty (Maybe Alias)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe Alias
forall a. Maybe a
Nothing
Text -> m ()
forall env (m :: * -> *). WithLog env Message m => Text -> m ()
logInfo (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text -> Text
T.strip (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$
Builder
"Running " Builder -> Builder -> Text
forall b. FromBuilder b => Builder -> Builder -> b
+| Builder
opName Builder -> Builder -> Builder
forall b. FromBuilder b => Builder -> Builder -> b
+| Builder
" by " Builder -> Builder -> Builder
forall b. FromBuilder b => Builder -> Builder -> b
+| AddressOrAlias
sender' AddressOrAlias -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+ Builder
":\n" Builder -> Builder -> Builder
forall b. FromBuilder b => Builder -> Builder -> b
+|
Text
-> ((OperationInfo ClientInput, Maybe Alias) -> Builder)
-> NonEmpty (OperationInfo ClientInput, Maybe Alias)
-> Builder
forall (f :: * -> *) a.
Foldable f =>
Text -> (a -> Builder) -> f a -> Builder
blockListF' Text
"-" (OperationInfo ClientInput, Maybe Alias) -> Builder
buildOp (NonEmpty (OperationInfo ClientInput)
ops NonEmpty (OperationInfo ClientInput)
-> NonEmpty (Maybe Alias)
-> NonEmpty (OperationInfo ClientInput, Maybe Alias)
forall a b. NonEmpty a -> NonEmpty b -> NonEmpty (a, b)
`NE.zip` NonEmpty (Maybe Alias)
aliases)
runOperations
:: forall m env.
( HasTezosRpc m
, HasTezosClient m
, WithClientLog env m
)
=> AddressOrAlias
-> [OperationInfo ClientInput]
-> m (Maybe OperationHash, [OperationInfo Result])
runOperations :: AddressOrAlias
-> [OperationInfo ClientInput]
-> m (Maybe OperationHash, [OperationInfo Result])
runOperations AddressOrAlias
sender [OperationInfo ClientInput]
operations = case [OperationInfo ClientInput]
operations of
[] -> (Maybe OperationHash, [OperationInfo Result])
-> m (Maybe OperationHash, [OperationInfo Result])
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe OperationHash
forall a. Maybe a
Nothing, [])
OperationInfo ClientInput
op : [OperationInfo ClientInput]
ops -> do
(OperationHash
opHash, NonEmpty (OperationInfo Result)
res) <- AddressOrAlias
-> NonEmpty (OperationInfo ClientInput)
-> m (OperationHash, NonEmpty (OperationInfo Result))
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
AddressOrAlias
-> NonEmpty (OperationInfo ClientInput)
-> m (OperationHash, NonEmpty (OperationInfo Result))
runOperationsNonEmpty AddressOrAlias
sender (NonEmpty (OperationInfo ClientInput)
-> m (OperationHash, NonEmpty (OperationInfo Result)))
-> NonEmpty (OperationInfo ClientInput)
-> m (OperationHash, NonEmpty (OperationInfo Result))
forall a b. (a -> b) -> a -> b
$ OperationInfo ClientInput
op OperationInfo ClientInput
-> [OperationInfo ClientInput]
-> NonEmpty (OperationInfo ClientInput)
forall a. a -> [a] -> NonEmpty a
:| [OperationInfo ClientInput]
ops
(Maybe OperationHash, [OperationInfo Result])
-> m (Maybe OperationHash, [OperationInfo Result])
forall (m :: * -> *) a. Monad m => a -> m a
return ((Maybe OperationHash, [OperationInfo Result])
-> m (Maybe OperationHash, [OperationInfo Result]))
-> (Maybe OperationHash, [OperationInfo Result])
-> m (Maybe OperationHash, [OperationInfo Result])
forall a b. (a -> b) -> a -> b
$ (OperationHash -> Maybe OperationHash
forall a. a -> Maybe a
Just OperationHash
opHash, NonEmpty (OperationInfo Result)
-> [Element (NonEmpty (OperationInfo Result))]
forall t. Container t => t -> [Element t]
toList NonEmpty (OperationInfo Result)
res)
runOperationsNonEmpty
:: forall m env.
( HasTezosRpc m
, HasTezosClient m
, WithClientLog env m
)
=> AddressOrAlias
-> NonEmpty (OperationInfo ClientInput)
-> m (OperationHash, NonEmpty (OperationInfo Result))
runOperationsNonEmpty :: AddressOrAlias
-> NonEmpty (OperationInfo ClientInput)
-> m (OperationHash, NonEmpty (OperationInfo Result))
runOperationsNonEmpty AddressOrAlias
sender NonEmpty (OperationInfo ClientInput)
operations =
AddressOrAlias
-> NonEmpty (OperationInfo ClientInput) -> m (RunResult 'RealRun)
forall (runMode :: RunMode) (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
SingI runMode) =>
AddressOrAlias
-> NonEmpty (OperationInfo ClientInput) -> m (RunResult runMode)
runOperationsNonEmptyHelper @'RealRun AddressOrAlias
sender NonEmpty (OperationInfo ClientInput)
operations
data RunMode = DryRun | RealRun
isRealRun :: forall (runMode :: RunMode). (SingI runMode) => Bool
isRealRun :: Bool
isRealRun = case SingI runMode => Sing runMode
forall k (a :: k). SingI a => Sing a
sing @runMode of
Sing runMode
SRealRun -> Bool
True
Sing runMode
SDryRun -> Bool
False
type family RunResult (a :: RunMode) where
RunResult 'DryRun = NonEmpty (AppliedResult, TezosMutez)
RunResult 'RealRun = (OperationHash, NonEmpty (OperationInfo Result))
data SingRunResult :: RunMode -> Type where
SDryRun :: SingRunResult 'DryRun
SRealRun :: SingRunResult 'RealRun
type instance Sing = SingRunResult
instance SingI 'DryRun where
sing :: Sing 'DryRun
sing = Sing 'DryRun
SingRunResult 'DryRun
SDryRun
instance SingI 'RealRun where
sing :: Sing 'RealRun
sing = Sing 'RealRun
SingRunResult 'RealRun
SRealRun
dryRunOperationsNonEmpty
:: forall m env.
( HasTezosRpc m
, HasTezosClient m
, WithClientLog env m
)
=> AddressOrAlias
-> NonEmpty (OperationInfo ClientInput)
-> m (NonEmpty (AppliedResult, TezosMutez))
dryRunOperationsNonEmpty :: AddressOrAlias
-> NonEmpty (OperationInfo ClientInput)
-> m (NonEmpty (AppliedResult, TezosMutez))
dryRunOperationsNonEmpty AddressOrAlias
sender NonEmpty (OperationInfo ClientInput)
operations =
AddressOrAlias
-> NonEmpty (OperationInfo ClientInput) -> m (RunResult 'DryRun)
forall (runMode :: RunMode) (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
SingI runMode) =>
AddressOrAlias
-> NonEmpty (OperationInfo ClientInput) -> m (RunResult runMode)
runOperationsNonEmptyHelper @'DryRun AddressOrAlias
sender NonEmpty (OperationInfo ClientInput)
operations
runOperationsNonEmptyHelper
:: forall (runMode :: RunMode) m env.
( HasTezosRpc m
, HasTezosClient m
, WithClientLog env m
, SingI runMode
)
=> AddressOrAlias
-> NonEmpty (OperationInfo ClientInput)
-> m (RunResult runMode)
runOperationsNonEmptyHelper :: AddressOrAlias
-> NonEmpty (OperationInfo ClientInput) -> m (RunResult runMode)
runOperationsNonEmptyHelper AddressOrAlias
sender NonEmpty (OperationInfo ClientInput)
operations = do
AddressOrAlias -> NonEmpty (OperationInfo ClientInput) -> m ()
forall (runMode :: RunMode) env (m :: * -> *).
(WithClientLog env m, HasTezosClient m, SingI runMode) =>
AddressOrAlias -> NonEmpty (OperationInfo ClientInput) -> m ()
logOperations @runMode AddressOrAlias
sender NonEmpty (OperationInfo ClientInput)
operations
Address
senderAddress <- AddressOrAlias -> m Address
forall (m :: * -> *).
(MonadThrow m, HasTezosClient m) =>
AddressOrAlias -> m Address
resolveAddress AddressOrAlias
sender
Address -> OperationInfo ClientInput -> m ()
prohibitContractSender Address
senderAddress (OperationInfo ClientInput -> m ())
-> OperationInfo ClientInput -> m ()
forall a b. (a -> b) -> a -> b
$ NonEmpty (OperationInfo ClientInput) -> OperationInfo ClientInput
forall a. NonEmpty a -> a
head NonEmpty (OperationInfo ClientInput)
operations
Maybe ScrubbedBytes
mbPassword <- Address -> m (Maybe ScrubbedBytes)
forall (m :: * -> *).
HasTezosClient m =>
Address -> m (Maybe ScrubbedBytes)
getKeyPassword Address
senderAddress
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (SingI runMode => Bool
forall (runMode :: RunMode). SingI runMode => Bool
isRealRun @runMode Bool -> Bool -> Bool
forall a. Boolean a => a -> a -> a
&& [OperationInfo ClientInput] -> Bool
forall i. [OperationInfo i] -> Bool
mayNeedSenderRevealing (NonEmpty (OperationInfo ClientInput)
-> [Element (NonEmpty (OperationInfo ClientInput))]
forall t. Container t => t -> [Element t]
toList NonEmpty (OperationInfo ClientInput)
operations)) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
Address -> Maybe ScrubbedBytes -> m ()
forall env (m :: * -> *).
(WithClientLog env m, HasTezosRpc m, HasTezosClient m) =>
Address -> Maybe ScrubbedBytes -> m ()
revealKeyUnlessRevealed Address
senderAddress Maybe ScrubbedBytes
mbPassword
ProtocolParameters
pp <- m ProtocolParameters
forall (m :: * -> *). HasTezosRpc m => m ProtocolParameters
getProtocolParameters
OperationConstants{Text
TezosInt64
FeeConstants
BlockConstants
ocCounter :: OperationConstants -> TezosInt64
ocFeeConstants :: OperationConstants -> FeeConstants
ocBlockConstants :: OperationConstants -> BlockConstants
ocLastBlockHash :: OperationConstants -> Text
ocCounter :: TezosInt64
ocFeeConstants :: FeeConstants
ocBlockConstants :: BlockConstants
ocLastBlockHash :: Text
..} <- Address -> m OperationConstants
forall (m :: * -> *).
HasTezosRpc m =>
Address -> m OperationConstants
preProcessOperation Address
senderAddress
let convertOps :: TezosInt64 -> OperationInfo ClientInput -> OperationInput
convertOps TezosInt64
i = CommonOperationData -> OperationInfo RPCInput -> OperationInput
OperationInput CommonOperationData
commonData (OperationInfo RPCInput -> OperationInput)
-> (OperationInfo ClientInput -> OperationInfo RPCInput)
-> OperationInfo ClientInput
-> OperationInput
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
OpTransfer (TransactionData TD {..}) ->
TransferInfo RPCInput -> OperationInfo RPCInput
forall i. TransferInfo i -> OperationInfo i
OpTransfer TransactionOperation :: TezosMutez -> Address -> ParametersInternal -> TransactionOperation
TransactionOperation
{ toDestination :: Address
toDestination = Address
tdReceiver
, toAmount :: TezosMutez
toAmount = Mutez -> TezosMutez
TezosMutez Mutez
tdAmount
, toParameters :: ParametersInternal
toParameters = EpName -> Value t -> ParametersInternal
forall (t :: T).
ParameterScope t =>
EpName -> Value t -> ParametersInternal
toParametersInternals EpName
tdEpName Value t
tdParam
}
OpOriginate OriginationData{..} ->
OriginationInfo RPCInput -> OperationInfo RPCInput
forall i. OriginationInfo i -> OperationInfo i
OpOriginate OriginationOperation :: TezosMutez -> OriginationScript -> OriginationOperation
OriginationOperation
{ ooBalance :: TezosMutez
ooBalance = Mutez -> TezosMutez
TezosMutez Mutez
odBalance
, ooScript :: OriginationScript
ooScript = Contract cp st -> Value st -> OriginationScript
forall (cp :: T) (st :: T).
Contract cp st -> Value st -> OriginationScript
mkOriginationScript Contract cp st
odContract Value st
odStorage
}
OpReveal RevealData{..} ->
RevealInfo RPCInput -> OperationInfo RPCInput
forall i. RevealInfo i -> OperationInfo i
OpReveal RevealOperation :: PublicKey -> RevealOperation
RevealOperation
{ roPublicKey :: PublicKey
roPublicKey = PublicKey
rdPublicKey
}
where
commonData :: CommonOperationData
commonData = Address -> TezosInt64 -> ProtocolParameters -> CommonOperationData
mkCommonOperationData Address
senderAddress (TezosInt64
ocCounter TezosInt64 -> TezosInt64 -> TezosInt64
forall a. Num a => a -> a -> a
+ TezosInt64
i) ProtocolParameters
pp
let opsToRun :: NonEmpty OperationInput
opsToRun = (TezosInt64 -> OperationInfo ClientInput -> OperationInput)
-> NonEmpty TezosInt64
-> NonEmpty (OperationInfo ClientInput)
-> NonEmpty OperationInput
forall a b c.
(a -> b -> c) -> NonEmpty a -> NonEmpty b -> NonEmpty c
NE.zipWith TezosInt64 -> OperationInfo ClientInput -> OperationInput
convertOps (TezosInt64
1 TezosInt64 -> [TezosInt64] -> NonEmpty TezosInt64
forall a. a -> [a] -> NonEmpty a
:| [(TezosInt64
2 :: TezosInt64)..]) NonEmpty (OperationInfo ClientInput)
operations
mbFees :: NonEmpty (Maybe Mutez)
mbFees = NonEmpty (OperationInfo ClientInput)
operations NonEmpty (OperationInfo ClientInput)
-> (OperationInfo ClientInput -> Maybe Mutez)
-> NonEmpty (Maybe Mutez)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
OpTransfer (TransactionData TD {..}) -> Maybe Mutez
tdMbFee
OpOriginate OriginationData{..} -> Maybe Mutez
odMbFee
OpReveal RevealData{..} -> Maybe Mutez
rdMbFee
let runOp :: RunOperation
runOp = RunOperation :: RunOperationInternal -> Text -> RunOperation
RunOperation
{ roOperation :: RunOperationInternal
roOperation = RunOperationInternal :: Text
-> NonEmpty OperationInput -> Signature -> RunOperationInternal
RunOperationInternal
{ roiBranch :: Text
roiBranch = Text
ocLastBlockHash
, roiContents :: NonEmpty OperationInput
roiContents = NonEmpty OperationInput
opsToRun
, roiSignature :: Signature
roiSignature = Signature
stubSignature
}
, roChainId :: Text
roChainId = BlockConstants -> Text
bcChainId BlockConstants
ocBlockConstants
}
NonEmpty AppliedResult
results <- Either RunOperation PreApplyOperation -> m (NonEmpty AppliedResult)
forall (m :: * -> *).
HasTezosRpc m =>
Either RunOperation PreApplyOperation -> m (NonEmpty AppliedResult)
getAppliedResults (RunOperation -> Either RunOperation PreApplyOperation
forall a b. a -> Either a b
Left RunOperation
runOp)
let
forgeOp :: NonEmpty OperationInput -> m ByteString
forgeOp :: NonEmpty OperationInput -> m ByteString
forgeOp NonEmpty OperationInput
ops =
(HexJSONByteString -> ByteString)
-> m HexJSONByteString -> m ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap HexJSONByteString -> ByteString
unHexJSONByteString (m HexJSONByteString -> m ByteString)
-> (ForgeOperation -> m HexJSONByteString)
-> ForgeOperation
-> m ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForgeOperation -> m HexJSONByteString
forall (m :: * -> *).
HasTezosRpc m =>
ForgeOperation -> m HexJSONByteString
forgeOperation (ForgeOperation -> m ByteString) -> ForgeOperation -> m ByteString
forall a b. (a -> b) -> a -> b
$ ForgeOperation :: Text -> NonEmpty OperationInput -> ForgeOperation
ForgeOperation
{ foBranch :: Text
foBranch = Text
ocLastBlockHash
, foContents :: NonEmpty OperationInput
foContents = NonEmpty OperationInput
ops
}
let
signForgedOp :: ByteString -> m (Signature, ByteString)
signForgedOp :: ByteString -> m (Signature, ByteString)
signForgedOp ByteString
op = do
Signature
signature' <- AddressOrAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature
forall (m :: * -> *).
HasTezosClient m =>
AddressOrAlias -> Maybe ScrubbedBytes -> ByteString -> m Signature
signBytes AddressOrAlias
sender Maybe ScrubbedBytes
mbPassword (ByteString -> ByteString
addOperationPrefix ByteString
op)
return (Signature
signature', ByteString -> Signature -> ByteString
prepareOpForInjection ByteString
op Signature
signature')
let
updateOp :: OperationInput
-> Maybe Mutez
-> AppliedResult
-> Bool
-> m (OperationInput, Maybe (Signature, ByteString))
updateOp OperationInput
opToRun Maybe Mutez
mbFee AppliedResult
ar Bool
isFirst = do
let storageLimit :: TezosInt64
storageLimit = [AppliedResult] -> ProtocolParameters -> TezosInt64
computeStorageLimit [AppliedResult
ar] ProtocolParameters
pp TezosInt64 -> TezosInt64 -> TezosInt64
forall a. Num a => a -> a -> a
+ TezosInt64
20
let gasLimit :: TezosInt64
gasLimit = AppliedResult -> TezosInt64
arConsumedGas AppliedResult
ar TezosInt64 -> TezosInt64 -> TezosInt64
forall a. Num a => a -> a -> a
+ TezosInt64
100
updateCommonDataForFee :: Mutez -> CommonOperationData -> CommonOperationData
updateCommonDataForFee Mutez
fee =
TezosInt64
-> TezosInt64
-> TezosMutez
-> CommonOperationData
-> CommonOperationData
updateCommonData TezosInt64
gasLimit TezosInt64
storageLimit (Mutez -> TezosMutez
TezosMutez Mutez
fee)
(Mutez
_fee, OperationInput
op, Maybe (Signature, ByteString)
mReadySignedOp) <- (Mutez -> m OperationInput)
-> (OperationInput -> m (Mutez, Maybe (Signature, ByteString)))
-> m (Mutez, OperationInput, Maybe (Signature, ByteString))
forall op extra (m :: * -> *).
Monad m =>
(Mutez -> m op) -> (op -> m (Mutez, extra)) -> m (Mutez, op, extra)
convergingFee
@OperationInput
@(Maybe (Signature, ByteString))
(\Mutez
fee ->
OperationInput -> m OperationInput
forall (m :: * -> *) a. Monad m => a -> m a
return (OperationInput -> m OperationInput)
-> OperationInput -> m OperationInput
forall a b. (a -> b) -> a -> b
$ OperationInput
opToRun OperationInput -> State OperationInput () -> OperationInput
forall s a. s -> State s a -> s
&~
(CommonOperationData -> Identity CommonOperationData)
-> OperationInput -> Identity OperationInput
Lens' OperationInput CommonOperationData
oiCommonDataL ((CommonOperationData -> Identity CommonOperationData)
-> OperationInput -> Identity OperationInput)
-> (CommonOperationData -> CommonOperationData)
-> State OperationInput ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
%= Mutez -> CommonOperationData -> CommonOperationData
updateCommonDataForFee Mutez
fee
)
(\OperationInput
op -> do
ByteString
forgedOp <- NonEmpty OperationInput -> m ByteString
forgeOp (NonEmpty OperationInput -> m ByteString)
-> NonEmpty OperationInput -> m ByteString
forall a b. (a -> b) -> a -> b
$ OneItem (NonEmpty OperationInput) -> NonEmpty OperationInput
forall x. One x => OneItem x -> x
one OneItem (NonEmpty OperationInput)
OperationInput
op
(Int
fullForgedOpLength, Maybe (Signature, ByteString)
mExtra) <-
if Bool
isFirst
then do
res :: (Signature, ByteString)
res@(Signature
_signature, ByteString
signedOp) <- ByteString -> m (Signature, ByteString)
signForgedOp ByteString
forgedOp
(Int, Maybe (Signature, ByteString))
-> m (Int, Maybe (Signature, ByteString))
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> Int
forall t. Container t => t -> Int
length ByteString
signedOp, (Signature, ByteString) -> Maybe (Signature, ByteString)
forall a. a -> Maybe a
Just (Signature, ByteString)
res)
else
(Int, Maybe (Signature, ByteString))
-> m (Int, Maybe (Signature, ByteString))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Int
forall t. Container t => t -> Int
length ByteString
forgedOp Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
32, Maybe (Signature, ByteString)
forall a. Maybe a
Nothing)
(Mutez, Maybe (Signature, ByteString))
-> m (Mutez, Maybe (Signature, ByteString))
forall (m :: * -> *) a. Monad m => a -> m a
return
( Mutez -> (Mutez -> Mutez) -> Maybe Mutez -> Mutez
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (FeeConstants -> Int -> TezosInt64 -> Mutez
computeFee FeeConstants
ocFeeConstants Int
fullForgedOpLength TezosInt64
gasLimit) Mutez -> Mutez
forall a. a -> a
id Maybe Mutez
mbFee
, Maybe (Signature, ByteString)
mExtra
)
)
(OperationInput, Maybe (Signature, ByteString))
-> m (OperationInput, Maybe (Signature, ByteString))
forall (m :: * -> *) a. Monad m => a -> m a
return (OperationInput
op, Maybe (Signature, ByteString)
mReadySignedOp)
let
zipWith4NE
:: (a -> b -> c -> d -> e) -> NonEmpty a -> NonEmpty b -> NonEmpty c -> NonEmpty d
-> NonEmpty e
zipWith4NE :: (a -> b -> c -> d -> e)
-> NonEmpty a
-> NonEmpty b
-> NonEmpty c
-> NonEmpty d
-> NonEmpty e
zipWith4NE a -> b -> c -> d -> e
f (a
a :| [a]
as) (b
b :| [b]
bs) (c
c :| [c]
cs) (d
d :| [d]
ds) =
(a -> b -> c -> d -> e
f a
a b
b c
c d
d) e -> [e] -> NonEmpty e
forall a. a -> [a] -> NonEmpty a
:| (a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
forall a b c d e.
(a -> b -> c -> d -> e) -> [a] -> [b] -> [c] -> [d] -> [e]
zipWith4 a -> b -> c -> d -> e
f [a]
as [b]
bs [c]
cs [d]
ds
(NonEmpty OperationInput
updOps, NonEmpty (Maybe (Signature, ByteString))
readySignedOps) <- (NonEmpty (OperationInput, Maybe (Signature, ByteString))
-> (NonEmpty OperationInput,
NonEmpty (Maybe (Signature, ByteString))))
-> m (NonEmpty (OperationInput, Maybe (Signature, ByteString)))
-> m (NonEmpty OperationInput,
NonEmpty (Maybe (Signature, ByteString)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmpty (OperationInput, Maybe (Signature, ByteString))
-> (NonEmpty OperationInput,
NonEmpty (Maybe (Signature, ByteString)))
forall (f :: * -> *) a b. Functor f => f (a, b) -> (f a, f b)
NE.unzip (m (NonEmpty (OperationInput, Maybe (Signature, ByteString)))
-> m (NonEmpty OperationInput,
NonEmpty (Maybe (Signature, ByteString))))
-> (NonEmpty (m (OperationInput, Maybe (Signature, ByteString)))
-> m (NonEmpty (OperationInput, Maybe (Signature, ByteString))))
-> NonEmpty (m (OperationInput, Maybe (Signature, ByteString)))
-> m (NonEmpty OperationInput,
NonEmpty (Maybe (Signature, ByteString)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty (m (OperationInput, Maybe (Signature, ByteString)))
-> m (NonEmpty (OperationInput, Maybe (Signature, ByteString)))
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
sequenceA (NonEmpty (m (OperationInput, Maybe (Signature, ByteString)))
-> m (NonEmpty OperationInput,
NonEmpty (Maybe (Signature, ByteString))))
-> NonEmpty (m (OperationInput, Maybe (Signature, ByteString)))
-> m (NonEmpty OperationInput,
NonEmpty (Maybe (Signature, ByteString)))
forall a b. (a -> b) -> a -> b
$
(OperationInput
-> Maybe Mutez
-> AppliedResult
-> Bool
-> m (OperationInput, Maybe (Signature, ByteString)))
-> NonEmpty OperationInput
-> NonEmpty (Maybe Mutez)
-> NonEmpty AppliedResult
-> NonEmpty Bool
-> NonEmpty (m (OperationInput, Maybe (Signature, ByteString)))
forall a b c d e.
(a -> b -> c -> d -> e)
-> NonEmpty a
-> NonEmpty b
-> NonEmpty c
-> NonEmpty d
-> NonEmpty e
zipWith4NE OperationInput
-> Maybe Mutez
-> AppliedResult
-> Bool
-> m (OperationInput, Maybe (Signature, ByteString))
updateOp NonEmpty OperationInput
opsToRun NonEmpty (Maybe Mutez)
mbFees NonEmpty AppliedResult
results (Bool
True Bool -> [Bool] -> NonEmpty Bool
forall a. a -> [a] -> NonEmpty a
:| Bool -> [Bool]
forall a. a -> [a]
repeat Bool
False)
(Signature
signature', ByteString
signedOp) <- case NonEmpty (Maybe (Signature, ByteString))
readySignedOps of
Just (Signature, ByteString)
readyOp :| [] -> (Signature, ByteString) -> m (Signature, ByteString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Signature, ByteString)
readyOp
NonEmpty (Maybe (Signature, ByteString))
_ -> NonEmpty OperationInput -> m ByteString
forgeOp NonEmpty OperationInput
updOps m ByteString
-> (ByteString -> m (Signature, ByteString))
-> m (Signature, ByteString)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> m (Signature, ByteString)
signForgedOp
let preApplyOp :: PreApplyOperation
preApplyOp = PreApplyOperation :: Text
-> Text
-> NonEmpty OperationInput
-> Signature
-> PreApplyOperation
PreApplyOperation
{ paoProtocol :: Text
paoProtocol = BlockConstants -> Text
bcProtocol BlockConstants
ocBlockConstants
, paoBranch :: Text
paoBranch = Text
ocLastBlockHash
, paoContents :: NonEmpty OperationInput
paoContents = NonEmpty OperationInput
updOps
, paoSignature :: Signature
paoSignature = Signature
signature'
}
NonEmpty AppliedResult
ars2 <- Either RunOperation PreApplyOperation -> m (NonEmpty AppliedResult)
forall (m :: * -> *).
HasTezosRpc m =>
Either RunOperation PreApplyOperation -> m (NonEmpty AppliedResult)
getAppliedResults (PreApplyOperation -> Either RunOperation PreApplyOperation
forall a b. b -> Either a b
Right PreApplyOperation
preApplyOp)
case SingI runMode => Sing runMode
forall k (a :: k). SingI a => Sing a
sing @runMode of
Sing runMode
SDryRun -> do
let fees :: NonEmpty TezosMutez
fees = (OperationInput -> TezosMutez)
-> NonEmpty OperationInput -> NonEmpty TezosMutez
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (CommonOperationData -> TezosMutez
codFee (CommonOperationData -> TezosMutez)
-> (OperationInput -> CommonOperationData)
-> OperationInput
-> TezosMutez
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OperationInput -> CommonOperationData
oiCommonData) NonEmpty OperationInput
updOps
NonEmpty (AppliedResult, TezosMutez)
-> m (NonEmpty (AppliedResult, TezosMutez))
forall (m :: * -> *) a. Monad m => a -> m a
return (NonEmpty (AppliedResult, TezosMutez)
-> m (NonEmpty (AppliedResult, TezosMutez)))
-> NonEmpty (AppliedResult, TezosMutez)
-> m (NonEmpty (AppliedResult, TezosMutez))
forall a b. (a -> b) -> a -> b
$ NonEmpty AppliedResult
-> NonEmpty TezosMutez -> NonEmpty (AppliedResult, TezosMutez)
forall a b. NonEmpty a -> NonEmpty b -> NonEmpty (a, b)
NE.zip NonEmpty AppliedResult
ars2 NonEmpty TezosMutez
fees
Sing runMode
SRealRun -> do
OperationHash
operationHash <- HexJSONByteString -> m OperationHash
forall (m :: * -> *).
HasTezosRpc m =>
HexJSONByteString -> m OperationHash
injectOperation (ByteString -> HexJSONByteString
HexJSONByteString ByteString
signedOp)
OperationHash -> m ()
forall (m :: * -> *). HasTezosClient m => OperationHash -> m ()
waitForOperation OperationHash
operationHash
let contractAddrs :: NonEmpty [Address]
contractAddrs = AppliedResult -> [Address]
arOriginatedContracts (AppliedResult -> [Address])
-> NonEmpty AppliedResult -> NonEmpty [Address]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty AppliedResult
ars2
NonEmpty (OperationInfo Result)
opsRes <- NonEmpty (OperationInfo ClientInput, [Address])
-> ((OperationInfo ClientInput, [Address])
-> m (OperationInfo Result))
-> m (NonEmpty (OperationInfo Result))
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (NonEmpty (OperationInfo ClientInput)
-> NonEmpty [Address]
-> NonEmpty (OperationInfo ClientInput, [Address])
forall a b. NonEmpty a -> NonEmpty b -> NonEmpty (a, b)
NE.zip NonEmpty (OperationInfo ClientInput)
operations NonEmpty [Address]
contractAddrs) (((OperationInfo ClientInput, [Address])
-> m (OperationInfo Result))
-> m (NonEmpty (OperationInfo Result)))
-> ((OperationInfo ClientInput, [Address])
-> m (OperationInfo Result))
-> m (NonEmpty (OperationInfo Result))
forall a b. (a -> b) -> a -> b
$ \case
(OpTransfer TransferInfo ClientInput
_, []) ->
OperationInfo Result -> m (OperationInfo Result)
forall (m :: * -> *) a. Monad m => a -> m a
return (OperationInfo Result -> m (OperationInfo Result))
-> OperationInfo Result -> m (OperationInfo Result)
forall a b. (a -> b) -> a -> b
$ TransferInfo Result -> OperationInfo Result
forall i. TransferInfo i -> OperationInfo i
OpTransfer ()
(OpTransfer TransferInfo ClientInput
_, [Address]
addrs) -> do
Text -> m ()
forall env (m :: * -> *). WithLog env Message m => Text -> m ()
logInfo (Text -> m ()) -> (Text -> Text) -> Text -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$
Builder
"The following contracts were originated during transactions: " Builder -> Builder -> Text
forall b. FromBuilder b => Builder -> Builder -> b
+|
[Address] -> Builder
forall (f :: * -> *) a. (Foldable f, Buildable a) => f a -> Builder
listF [Address]
addrs Builder -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+ Builder
""
return $ TransferInfo Result -> OperationInfo Result
forall i. TransferInfo i -> OperationInfo i
OpTransfer ()
(OpOriginate OriginationInfo ClientInput
_, []) ->
IncorrectRpcResponse -> m (OperationInfo Result)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM IncorrectRpcResponse
RpcOriginatedNoContracts
(OpOriginate OriginationData{..}, [Address
addr]) -> do
Text -> m ()
forall env (m :: * -> *). WithLog env Message m => Text -> m ()
logDebug (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Builder
"Saving " Builder -> Builder -> Text
forall b. FromBuilder b => Builder -> Builder -> b
+| Address
addr Address -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+ Builder
" for " Builder -> Builder -> Builder
forall b. FromBuilder b => Builder -> Builder -> b
+| AliasHint
odName AliasHint -> Builder -> Builder
forall a b. (Buildable a, FromBuilder b) => a -> Builder -> b
|+ Builder
"\n"
Bool -> Address -> AliasOrAliasHint -> m ()
forall (m :: * -> *).
HasTezosClient m =>
Bool -> Address -> AliasOrAliasHint -> m ()
rememberContract Bool
odReplaceExisting Address
addr (AliasHint -> AliasOrAliasHint
AnAliasHint AliasHint
odName)
Alias
alias <- AddressOrAlias -> m Alias
forall (m :: * -> *). HasTezosClient m => AddressOrAlias -> m Alias
getAlias (AddressOrAlias -> m Alias) -> AddressOrAlias -> m Alias
forall a b. (a -> b) -> a -> b
$ Address -> AddressOrAlias
AddressResolved Address
addr
Text -> m ()
forall env (m :: * -> *). WithLog env Message m => Text -> m ()
logInfo (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Originated contract: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Alias -> Text
forall a b. (Buildable a, FromBuilder b) => a -> b
pretty Alias
alias
return $ OriginationInfo Result -> OperationInfo Result
forall i. OriginationInfo i -> OperationInfo i
OpOriginate OriginationInfo Result
Address
addr
(OpOriginate OriginationInfo ClientInput
_, addrs :: [Address]
addrs@(Address
_ : Address
_ : [Address]
_)) ->
IncorrectRpcResponse -> m (OperationInfo Result)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IncorrectRpcResponse -> m (OperationInfo Result))
-> IncorrectRpcResponse -> m (OperationInfo Result)
forall a b. (a -> b) -> a -> b
$ [Address] -> IncorrectRpcResponse
RpcOriginatedMoreContracts [Address]
addrs
(OpReveal RevealInfo ClientInput
_, [Address]
_) ->
OperationInfo Result -> m (OperationInfo Result)
forall (m :: * -> *) a. Monad m => a -> m a
return (OperationInfo Result -> m (OperationInfo Result))
-> OperationInfo Result -> m (OperationInfo Result)
forall a b. (a -> b) -> a -> b
$ RevealInfo Result -> OperationInfo Result
forall i. RevealInfo i -> OperationInfo i
OpReveal ()
NonEmpty AppliedResult
-> (Element (NonEmpty AppliedResult) -> m ()) -> m ()
forall t (m :: * -> *) b.
(Container t, Monad m) =>
t -> (Element t -> m b) -> m ()
forM_ NonEmpty AppliedResult
ars2 Element (NonEmpty AppliedResult) -> m ()
AppliedResult -> m ()
logStatistics
return (OperationHash
operationHash, NonEmpty (OperationInfo Result)
opsRes)
where
mayNeedSenderRevealing :: [OperationInfo i] -> Bool
mayNeedSenderRevealing :: [OperationInfo i] -> Bool
mayNeedSenderRevealing = (Element [OperationInfo i] -> Bool) -> [OperationInfo i] -> Bool
forall t. Container t => (Element t -> Bool) -> t -> Bool
any \case
OpTransfer{} -> Bool
True
OpOriginate{} -> Bool
True
OpReveal{} -> Bool
False
logStatistics :: AppliedResult -> m ()
logStatistics :: AppliedResult -> m ()
logStatistics AppliedResult
ar = do
let showTezosInt64 :: TezosInt64 -> Text
showTezosInt64 = Int64 -> Text
forall b a. (PrettyShow a, Show a, IsString b) => a -> b
show (Int64 -> Text) -> (TezosInt64 -> Int64) -> TezosInt64 -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TezosInt64 -> Int64
forall a. StringEncode a -> a
unStringEncode
Text -> m ()
forall env (m :: * -> *). WithLog env Message m => Text -> m ()
logInfo (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Consumed gas: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> TezosInt64 -> Text
showTezosInt64 (AppliedResult -> TezosInt64
arConsumedGas AppliedResult
ar)
Text -> m ()
forall env (m :: * -> *). WithLog env Message m => Text -> m ()
logInfo (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Storage size: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> TezosInt64 -> Text
showTezosInt64 (AppliedResult -> TezosInt64
arStorageSize AppliedResult
ar)
Text -> m ()
forall env (m :: * -> *). WithLog env Message m => Text -> m ()
logInfo (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Paid storage size diff: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> TezosInt64 -> Text
showTezosInt64 (AppliedResult -> TezosInt64
arPaidStorageDiff AppliedResult
ar)
prohibitContractSender :: Address -> OperationInfo ClientInput -> m ()
prohibitContractSender :: Address -> OperationInfo ClientInput -> m ()
prohibitContractSender Address
addr OperationInfo ClientInput
op = case (Address
addr, OperationInfo ClientInput
op) of
(KeyAddress KeyHash
_, OperationInfo ClientInput
_) -> m ()
forall (f :: * -> *). Applicative f => f ()
pass
(ContractAddress ContractHash
_, OperationInfo ClientInput
op') -> TezosClientError -> m ()
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (TezosClientError -> m ()) -> TezosClientError -> m ()
forall a b. (a -> b) -> a -> b
$ Address -> Text -> TezosClientError
ContractSender Address
addr (OperationInfo ClientInput -> Text
forall i. OperationInfo i -> Text
opName OperationInfo ClientInput
op')
opName :: OperationInfo i -> Text
opName = \case
OpTransfer TransferInfo i
_ -> Text
"transfer"
OpOriginate OriginationInfo i
_ -> Text
"origination"
OpReveal RevealInfo i
_ -> Text
"reveal"