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

-- | Functions to originate smart contracts via @octez-client@ and node RPC.
module Morley.Client.Action.Origination
  ( originateContract
  , originateContracts
  , originateUntypedContract
  -- Lorentz version
  , lOriginateContract
  , lOriginateContracts

  -- * Large originations
  , originateLargeContracts
  , originateLargeContract
  , originateLargeUntypedContract
  -- Lorentz version
  , lOriginateLargeContracts
  , lOriginateLargeContract

  -- Datatypes for batch originations
  , LOriginationData (..)
  , OriginationData (..)
  ) where

import Data.Default (def)
import Lorentz qualified as L
import Lorentz.Constraints
import Morley.Client.Action.Common
import Morley.Client.Action.Operation
import Morley.Client.Action.Origination.Large
import Morley.Client.Action.Transaction (runTransactions)
import Morley.Client.Logging
import Morley.Client.RPC.Class
import Morley.Client.RPC.Error
import Morley.Client.RPC.Types
import Morley.Client.TezosClient
import Morley.Client.Types
import Morley.Michelson.TypeCheck (typeCheckContractAndStorage, typeCheckingWith)
import Morley.Michelson.Typed (Contract, IsoValue(..), SomeContractAndStorage(..), Value)
import Morley.Michelson.Typed.Scope
import Morley.Michelson.Untyped qualified as U
import Morley.Tezos.Address
import Morley.Tezos.Address.Alias
import Morley.Tezos.Core
import Morley.Util.Exception

-- | Originate given contracts with given initial storages. Returns
-- operation hash (or @Nothing@ in case empty list was provided)
-- and originated contracts' addresses.
originateContracts
  :: forall m env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     )
  => ImplicitAddressOrAlias
  -> [OriginationData]
  -> m (Maybe OperationHash, [ContractAddress])
originateContracts :: forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
originateContracts ImplicitAddressOrAlias
sender [OriginationData]
originations = do
  (Maybe OperationHash
opHash, [OperationInfo Result]
res) <- ImplicitAddressOrAlias
-> [OperationInfo ClientInput]
-> m (Maybe OperationHash, [OperationInfo Result])
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [OperationInfo ClientInput]
-> m (Maybe OperationHash, [OperationInfo Result])
runOperations ImplicitAddressOrAlias
sender (OriginationData -> OperationInfo ClientInput
forall i. OriginationInfo i -> OperationInfo i
OpOriginate (OriginationData -> OperationInfo ClientInput)
-> [OriginationData] -> [OperationInfo ClientInput]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [OriginationData]
originations)
  (Maybe OperationHash, [ContractAddress])
-> m (Maybe OperationHash, [ContractAddress])
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe OperationHash
opHash, OperationInfo Result -> ContractAddress
forall {i}. OperationInfo i -> OriginationInfo i
fromOrigination (OperationInfo Result -> ContractAddress)
-> [OperationInfo Result] -> [ContractAddress]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [OperationInfo Result]
res)
  where
    fromOrigination :: OperationInfo i -> OriginationInfo i
fromOrigination = \case
      OpOriginate OriginationInfo i
r -> OriginationInfo i
r
      OperationInfo i
_ -> Text -> OriginationInfo i
forall a. HasCallStack => Text -> a
error Text
"Unexpectedly not origination"

-- | Originate single contract
originateContract
  :: forall m cp st env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     , StorageScope st
     , ParameterScope cp
     )
  => AliasBehavior
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> Contract cp st
  -> Value st
  -> Maybe Mutez
  -> Maybe L.KeyHash
  -> m (OperationHash, ContractAddress)
originateContract :: forall (m :: * -> *) (cp :: T) (st :: T) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 StorageScope st, ParameterScope cp) =>
AliasBehavior
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> Maybe KeyHash
-> m (OperationHash, ContractAddress)
originateContract AliasBehavior
odAliasBehavior ContractAlias
odName ImplicitAddressOrAlias
sender' Mutez
odBalance Contract cp st
odContract Value st
odStorage Maybe Mutez
odMbFee Maybe KeyHash
odDelegate = do
  (Maybe OperationHash
hash, [ContractAddress]
contracts) <- ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
originateContracts ImplicitAddressOrAlias
sender' [OriginationData :: forall (cp :: T) (st :: T).
(ParameterScope cp, StorageScope st) =>
AliasBehavior
-> ContractAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe KeyHash
-> Maybe Mutez
-> OriginationData
OriginationData{Maybe KeyHash
Maybe Mutez
ContractAlias
AliasBehavior
Mutez
Contract cp st
Value st
odMbFee :: Maybe Mutez
odDelegate :: Maybe KeyHash
odStorage :: Value st
odContract :: Contract cp st
odBalance :: Mutez
odName :: ContractAlias
odAliasBehavior :: AliasBehavior
odDelegate :: Maybe KeyHash
odMbFee :: Maybe Mutez
odStorage :: Value st
odContract :: Contract cp st
odBalance :: Mutez
odName :: ContractAlias
odAliasBehavior :: AliasBehavior
..}]
  Maybe OperationHash
-> [ContractAddress] -> m (OperationHash, ContractAddress)
forall (m :: * -> *).
HasTezosRpc m =>
Maybe OperationHash
-> [ContractAddress] -> m (OperationHash, ContractAddress)
singleOriginatedContract Maybe OperationHash
hash [ContractAddress]
contracts

-- | Originate a single untyped contract
originateUntypedContract
  :: forall m env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     )
  => AliasBehavior
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> U.Contract
  -> U.Value
  -> Maybe Mutez
  -> Maybe L.KeyHash
  -> m (OperationHash, ContractAddress)
originateUntypedContract :: forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
AliasBehavior
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract
-> Value
-> Maybe Mutez
-> Maybe KeyHash
-> m (OperationHash, ContractAddress)
originateUntypedContract AliasBehavior
aliasBehavior ContractAlias
name ImplicitAddressOrAlias
sender' Mutez
balance Contract
uContract Value
initialStorage Maybe Mutez
mbFee Maybe KeyHash
mbDelegate = do
  SomeContractAndStorage Contract cp st
contract Value st
storage <-
    m (Either (TcError' ExpandedOp) SomeContractAndStorage)
-> m SomeContractAndStorage
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
m (Either e a) -> m a
throwLeft (m (Either (TcError' ExpandedOp) SomeContractAndStorage)
 -> m SomeContractAndStorage)
-> (TypeCheckResult ExpandedOp SomeContractAndStorage
    -> m (Either (TcError' ExpandedOp) SomeContractAndStorage))
-> TypeCheckResult ExpandedOp SomeContractAndStorage
-> m SomeContractAndStorage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either (TcError' ExpandedOp) SomeContractAndStorage
-> m (Either (TcError' ExpandedOp) SomeContractAndStorage)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either (TcError' ExpandedOp) SomeContractAndStorage
 -> m (Either (TcError' ExpandedOp) SomeContractAndStorage))
-> (TypeCheckResult ExpandedOp SomeContractAndStorage
    -> Either (TcError' ExpandedOp) SomeContractAndStorage)
-> TypeCheckResult ExpandedOp SomeContractAndStorage
-> m (Either (TcError' ExpandedOp) SomeContractAndStorage)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeCheckOptions
-> TypeCheckResult ExpandedOp SomeContractAndStorage
-> Either (TcError' ExpandedOp) SomeContractAndStorage
forall op a.
TypeCheckOptions -> TypeCheckResult op a -> Either (TcError' op) a
typeCheckingWith TypeCheckOptions
forall a. Default a => a
def (TypeCheckResult ExpandedOp SomeContractAndStorage
 -> m SomeContractAndStorage)
-> TypeCheckResult ExpandedOp SomeContractAndStorage
-> m SomeContractAndStorage
forall a b. (a -> b) -> a -> b
$
      Contract
-> Value -> TypeCheckResult ExpandedOp SomeContractAndStorage
typeCheckContractAndStorage Contract
uContract Value
initialStorage
  AliasBehavior
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> Maybe KeyHash
-> m (OperationHash, ContractAddress)
forall (m :: * -> *) (cp :: T) (st :: T) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 StorageScope st, ParameterScope cp) =>
AliasBehavior
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> Maybe KeyHash
-> m (OperationHash, ContractAddress)
originateContract AliasBehavior
aliasBehavior ContractAlias
name ImplicitAddressOrAlias
sender' Mutez
balance Contract cp st
contract Value st
storage Maybe Mutez
mbFee Maybe KeyHash
mbDelegate

-- | Lorentz version of 'originateContracts'
lOriginateContracts
  :: forall m env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     )
  => ImplicitAddressOrAlias
  -> [LOriginationData]
  -> m (Maybe OperationHash, [ContractAddress])
lOriginateContracts :: forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [LOriginationData] -> m (Maybe OperationHash, [ContractAddress])
lOriginateContracts ImplicitAddressOrAlias
sender' [LOriginationData]
originations =
  ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
originateContracts ImplicitAddressOrAlias
sender' ([OriginationData] -> m (Maybe OperationHash, [ContractAddress]))
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
forall a b. (a -> b) -> a -> b
$ (LOriginationData -> OriginationData)
-> [LOriginationData] -> [OriginationData]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map LOriginationData -> OriginationData
convertLOriginationData [LOriginationData]
originations

-- | Originate single Lorentz contract
lOriginateContract
  :: forall m cp st vd env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     , NiceStorage st
     , NiceParameterFull cp
     )
  => AliasBehavior
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> L.Contract cp st vd
  -> st
  -> Maybe Mutez
  -> Maybe L.KeyHash
  -> m (OperationHash, ContractAddress)
lOriginateContract :: forall (m :: * -> *) cp st vd env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 NiceStorage st, NiceParameterFull cp) =>
AliasBehavior
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st vd
-> st
-> Maybe Mutez
-> Maybe KeyHash
-> m (OperationHash, ContractAddress)
lOriginateContract AliasBehavior
lodAliasBehavior ContractAlias
lodName ImplicitAddressOrAlias
sender' Mutez
lodBalance Contract cp st vd
lodContract st
lodStorage Maybe Mutez
lodMbFee Maybe KeyHash
lodDelegate = do
  (Maybe OperationHash
hash, [ContractAddress]
contracts) <- ImplicitAddressOrAlias
-> [LOriginationData] -> m (Maybe OperationHash, [ContractAddress])
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [LOriginationData] -> m (Maybe OperationHash, [ContractAddress])
lOriginateContracts ImplicitAddressOrAlias
sender' [LOriginationData :: forall cp st vd.
(NiceParameterFull cp, NiceStorage st) =>
AliasBehavior
-> ContractAlias
-> Mutez
-> Contract cp st vd
-> st
-> Maybe KeyHash
-> Maybe Mutez
-> LOriginationData
LOriginationData{st
Maybe KeyHash
Maybe Mutez
ContractAlias
AliasBehavior
Mutez
Contract cp st vd
lodMbFee :: Maybe Mutez
lodDelegate :: Maybe KeyHash
lodStorage :: st
lodContract :: Contract cp st vd
lodBalance :: Mutez
lodName :: ContractAlias
lodAliasBehavior :: AliasBehavior
lodDelegate :: Maybe KeyHash
lodMbFee :: Maybe Mutez
lodStorage :: st
lodContract :: Contract cp st vd
lodBalance :: Mutez
lodName :: ContractAlias
lodAliasBehavior :: AliasBehavior
..}]
  forall (m :: * -> *).
HasTezosRpc m =>
Maybe OperationHash
-> [ContractAddress] -> m (OperationHash, ContractAddress)
singleOriginatedContract @m Maybe OperationHash
hash [ContractAddress]
contracts

--------------------------------------------------------------------------------
-- Large Originations
--------------------------------------------------------------------------------

-- | Automated multi-step origination process for contracts that don't fit into
-- the origination limit. See "Morley.Client.Action.Origination.Large".
originateLargeContracts
  :: forall m env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     )
  => ImplicitAddressOrAlias
  -> [OriginationData]
  -> m (Maybe OperationHash, [ContractAddress])
originateLargeContracts :: forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
originateLargeContracts ImplicitAddressOrAlias
sender' [OriginationData]
largeOriginations = do
  ImplicitAddress
senderAddress <- ImplicitAddressOrAlias
-> m (ResolvedAddress ImplicitAddressOrAlias)
forall addressOrAlias (m :: * -> *) env.
(HasTezosClient m, MonadThrow m, WithClientLog env m,
 Resolve addressOrAlias) =>
addressOrAlias -> m (ResolvedAddress addressOrAlias)
resolveAddress ImplicitAddressOrAlias
sender'
  -- calculate large contract originators
  let originators :: [LargeOriginationData]
originators = (OriginationData -> LargeOriginationData)
-> [OriginationData] -> [LargeOriginationData]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map OriginationData -> LargeOriginationData
mkLargeOriginationData [OriginationData]
largeOriginations
  -- originate them. Note: we use the operation hash from here even tho the
  -- large contracts are originated in another one, because those happen in
  -- several different transactions.
  (Maybe OperationHash
opHash, [ContractAddress]
originatorsAddr) <- ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
originateContracts ImplicitAddressOrAlias
sender' ([OriginationData] -> m (Maybe OperationHash, [ContractAddress]))
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
forall a b. (a -> b) -> a -> b
$
    (LargeOriginationData -> OriginationData)
-> [LargeOriginationData] -> [OriginationData]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (ImplicitAddress -> LargeOriginationData -> OriginationData
mkLargeOriginatorData ImplicitAddress
senderAddress) [LargeOriginationData]
originators
  -- run all the transactions needed (for each large contract originator)
  -- Note: it is not possible to run these all at once, because the node won't
  -- accept a transaction batch where the sum of the storage cost is over 16k,
  -- so here we need to run them one by one.
  (Element [TransactionData]
 -> m (Maybe (OperationHash, [OperationInfo Result])))
-> [TransactionData] -> m ()
forall t (m :: * -> *) b.
(Container t, Monad m) =>
(Element t -> m b) -> t -> m ()
mapM_ (ImplicitAddress
-> [TransactionData]
-> m (Maybe (OperationHash, [OperationInfo Result]))
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddress
-> [TransactionData]
-> m (Maybe (OperationHash, [OperationInfo Result]))
runTransactions ImplicitAddress
senderAddress ([TransactionData]
 -> m (Maybe (OperationHash, [OperationInfo Result])))
-> (TransactionData -> [TransactionData])
-> TransactionData
-> m (Maybe (OperationHash, [OperationInfo Result]))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TransactionData -> [TransactionData] -> [TransactionData]
forall a. a -> [a] -> [a]
: [])) ([TransactionData] -> m ())
-> ([[TransactionData]] -> [TransactionData])
-> [[TransactionData]]
-> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[TransactionData]] -> [TransactionData]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[TransactionData]] -> m ()) -> [[TransactionData]] -> m ()
forall a b. (a -> b) -> a -> b
$
    (ContractAddress -> LargeOriginationData -> [TransactionData])
-> [ContractAddress]
-> [LargeOriginationData]
-> [[TransactionData]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ContractAddress -> LargeOriginationData -> [TransactionData]
mkLargeOriginatorTransactions [ContractAddress]
originatorsAddr [LargeOriginationData]
originators
  -- get the addresses of the originated large contracts back from the originators
  -- and remember their addresses with their aliases
  [ContractAddress]
originatedContracts <- (ContractAddress -> OriginationData -> m ContractAddress)
-> [ContractAddress] -> [OriginationData] -> m [ContractAddress]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM ContractAddress -> OriginationData -> m ContractAddress
forall (m :: * -> *).
(HasTezosRpc m, HasTezosClient m) =>
ContractAddress -> OriginationData -> m ContractAddress
retrieveLargeContracts [ContractAddress]
originatorsAddr [OriginationData]
largeOriginations
  return (Maybe OperationHash
opHash, [ContractAddress]
originatedContracts)

-- | Originate a single large contract
originateLargeContract
  :: forall m cp st env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     , StorageScope st
     , ParameterScope cp
     )
  => AliasBehavior
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> Contract cp st
  -> Value st
  -> Maybe Mutez
  -> Maybe L.KeyHash
  -> m (OperationHash, ContractAddress)
originateLargeContract :: forall (m :: * -> *) (cp :: T) (st :: T) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 StorageScope st, ParameterScope cp) =>
AliasBehavior
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> Maybe KeyHash
-> m (OperationHash, ContractAddress)
originateLargeContract AliasBehavior
odAliasBehavior ContractAlias
odName ImplicitAddressOrAlias
sender' Mutez
odBalance Contract cp st
odContract Value st
odStorage Maybe Mutez
odMbFee Maybe KeyHash
odDelegate = do
  (Maybe OperationHash
hash, [ContractAddress]
contracts) <- ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
originateLargeContracts ImplicitAddressOrAlias
sender' [OriginationData :: forall (cp :: T) (st :: T).
(ParameterScope cp, StorageScope st) =>
AliasBehavior
-> ContractAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe KeyHash
-> Maybe Mutez
-> OriginationData
OriginationData{Maybe KeyHash
Maybe Mutez
ContractAlias
AliasBehavior
Mutez
Contract cp st
Value st
odDelegate :: Maybe KeyHash
odMbFee :: Maybe Mutez
odStorage :: Value st
odContract :: Contract cp st
odBalance :: Mutez
odName :: ContractAlias
odAliasBehavior :: AliasBehavior
odMbFee :: Maybe Mutez
odDelegate :: Maybe KeyHash
odStorage :: Value st
odContract :: Contract cp st
odBalance :: Mutez
odName :: ContractAlias
odAliasBehavior :: AliasBehavior
..}]
  forall (m :: * -> *).
HasTezosRpc m =>
Maybe OperationHash
-> [ContractAddress] -> m (OperationHash, ContractAddress)
singleOriginatedContract @m Maybe OperationHash
hash [ContractAddress]
contracts

-- | Originate a single untyped large contract
originateLargeUntypedContract
  :: forall m env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     )
  => AliasBehavior
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> U.Contract
  -> U.Value
  -> Maybe Mutez
  -> Maybe L.KeyHash
  -> m (OperationHash, ContractAddress)
originateLargeUntypedContract :: forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
AliasBehavior
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract
-> Value
-> Maybe Mutez
-> Maybe KeyHash
-> m (OperationHash, ContractAddress)
originateLargeUntypedContract AliasBehavior
aliasBehavior ContractAlias
name ImplicitAddressOrAlias
sender' Mutez
balance Contract
uContract Value
initialStorage Maybe Mutez
mbFee Maybe KeyHash
mbDelegate = do
  SomeContractAndStorage Contract cp st
contract Value st
storage <-
    m (Either (TcError' ExpandedOp) SomeContractAndStorage)
-> m SomeContractAndStorage
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
m (Either e a) -> m a
throwLeft (m (Either (TcError' ExpandedOp) SomeContractAndStorage)
 -> m SomeContractAndStorage)
-> (TypeCheckResult ExpandedOp SomeContractAndStorage
    -> m (Either (TcError' ExpandedOp) SomeContractAndStorage))
-> TypeCheckResult ExpandedOp SomeContractAndStorage
-> m SomeContractAndStorage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either (TcError' ExpandedOp) SomeContractAndStorage
-> m (Either (TcError' ExpandedOp) SomeContractAndStorage)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either (TcError' ExpandedOp) SomeContractAndStorage
 -> m (Either (TcError' ExpandedOp) SomeContractAndStorage))
-> (TypeCheckResult ExpandedOp SomeContractAndStorage
    -> Either (TcError' ExpandedOp) SomeContractAndStorage)
-> TypeCheckResult ExpandedOp SomeContractAndStorage
-> m (Either (TcError' ExpandedOp) SomeContractAndStorage)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeCheckOptions
-> TypeCheckResult ExpandedOp SomeContractAndStorage
-> Either (TcError' ExpandedOp) SomeContractAndStorage
forall op a.
TypeCheckOptions -> TypeCheckResult op a -> Either (TcError' op) a
typeCheckingWith TypeCheckOptions
forall a. Default a => a
def (TypeCheckResult ExpandedOp SomeContractAndStorage
 -> m SomeContractAndStorage)
-> TypeCheckResult ExpandedOp SomeContractAndStorage
-> m SomeContractAndStorage
forall a b. (a -> b) -> a -> b
$
      Contract
-> Value -> TypeCheckResult ExpandedOp SomeContractAndStorage
typeCheckContractAndStorage Contract
uContract Value
initialStorage
  AliasBehavior
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> Maybe KeyHash
-> m (OperationHash, ContractAddress)
forall (m :: * -> *) (cp :: T) (st :: T) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 StorageScope st, ParameterScope cp) =>
AliasBehavior
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> Maybe KeyHash
-> m (OperationHash, ContractAddress)
originateLargeContract AliasBehavior
aliasBehavior ContractAlias
name ImplicitAddressOrAlias
sender' Mutez
balance Contract cp st
contract Value st
storage Maybe Mutez
mbFee Maybe KeyHash
mbDelegate

-- | Lorentz version of 'originateLargeContracts'
lOriginateLargeContracts
  :: forall m env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     )
  => ImplicitAddressOrAlias
  -> [LOriginationData]
  -> m (Maybe OperationHash, [ContractAddress])
lOriginateLargeContracts :: forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [LOriginationData] -> m (Maybe OperationHash, [ContractAddress])
lOriginateLargeContracts ImplicitAddressOrAlias
sender' [LOriginationData]
originations =
  ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
originateLargeContracts ImplicitAddressOrAlias
sender' ([OriginationData] -> m (Maybe OperationHash, [ContractAddress]))
-> [OriginationData] -> m (Maybe OperationHash, [ContractAddress])
forall a b. (a -> b) -> a -> b
$ (LOriginationData -> OriginationData)
-> [LOriginationData] -> [OriginationData]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map LOriginationData -> OriginationData
convertLOriginationData [LOriginationData]
originations

-- | Originate a single large Lorentz contract
lOriginateLargeContract
  :: forall m cp st vd env.
     ( HasTezosRpc m
     , HasTezosClient m
     , WithClientLog env m
     , NiceStorage st
     , NiceParameterFull cp
     )
  => AliasBehavior
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> L.Contract cp st vd
  -> st
  -> Maybe Mutez
  -> Maybe L.KeyHash
  -> m (OperationHash, ContractAddress)
lOriginateLargeContract :: forall (m :: * -> *) cp st vd env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 NiceStorage st, NiceParameterFull cp) =>
AliasBehavior
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st vd
-> st
-> Maybe Mutez
-> Maybe KeyHash
-> m (OperationHash, ContractAddress)
lOriginateLargeContract AliasBehavior
lodAliasBehavior ContractAlias
lodName ImplicitAddressOrAlias
sender' Mutez
lodBalance Contract cp st vd
lodContract st
lodStorage Maybe Mutez
lodMbFee Maybe KeyHash
lodDelegate = do
  (Maybe OperationHash
hash, [ContractAddress]
contracts) <- ImplicitAddressOrAlias
-> [LOriginationData] -> m (Maybe OperationHash, [ContractAddress])
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
ImplicitAddressOrAlias
-> [LOriginationData] -> m (Maybe OperationHash, [ContractAddress])
lOriginateLargeContracts ImplicitAddressOrAlias
sender' [LOriginationData :: forall cp st vd.
(NiceParameterFull cp, NiceStorage st) =>
AliasBehavior
-> ContractAlias
-> Mutez
-> Contract cp st vd
-> st
-> Maybe KeyHash
-> Maybe Mutez
-> LOriginationData
LOriginationData{st
Maybe KeyHash
Maybe Mutez
ContractAlias
AliasBehavior
Mutez
Contract cp st vd
lodDelegate :: Maybe KeyHash
lodMbFee :: Maybe Mutez
lodStorage :: st
lodContract :: Contract cp st vd
lodBalance :: Mutez
lodName :: ContractAlias
lodAliasBehavior :: AliasBehavior
lodMbFee :: Maybe Mutez
lodDelegate :: Maybe KeyHash
lodStorage :: st
lodContract :: Contract cp st vd
lodBalance :: Mutez
lodName :: ContractAlias
lodAliasBehavior :: AliasBehavior
..}]
  forall (m :: * -> *).
HasTezosRpc m =>
Maybe OperationHash
-> [ContractAddress] -> m (OperationHash, ContractAddress)
singleOriginatedContract @m Maybe OperationHash
hash [ContractAddress]
contracts

--------------------------------------------------------------------------------
-- Utilities
--------------------------------------------------------------------------------

-- | Lorentz version of 'OriginationData'
data LOriginationData = forall cp st vd. (NiceParameterFull cp, NiceStorage st)
  => LOriginationData
  { LOriginationData -> AliasBehavior
lodAliasBehavior :: AliasBehavior
  , LOriginationData -> ContractAlias
lodName :: ContractAlias
  , LOriginationData -> Mutez
lodBalance :: Mutez
  , ()
lodContract :: L.Contract cp st vd
  , ()
lodStorage :: st
  , LOriginationData -> Maybe KeyHash
lodDelegate :: Maybe L.KeyHash
  , LOriginationData -> Maybe Mutez
lodMbFee :: Maybe Mutez
  }

convertLOriginationData :: LOriginationData -> OriginationData
convertLOriginationData :: LOriginationData -> OriginationData
convertLOriginationData LOriginationData {st
Maybe KeyHash
Maybe Mutez
ContractAlias
AliasBehavior
Mutez
Contract cp st vd
lodMbFee :: Maybe Mutez
lodDelegate :: Maybe KeyHash
lodStorage :: st
lodContract :: Contract cp st vd
lodBalance :: Mutez
lodName :: ContractAlias
lodAliasBehavior :: AliasBehavior
lodMbFee :: LOriginationData -> Maybe Mutez
lodDelegate :: LOriginationData -> Maybe KeyHash
lodStorage :: ()
lodContract :: ()
lodBalance :: LOriginationData -> Mutez
lodName :: LOriginationData -> ContractAlias
lodAliasBehavior :: LOriginationData -> AliasBehavior
..} = case Contract cp st vd
lodContract of
  (Contract cp st vd
_ :: L.Contract cp st vd) ->
    OriginationData :: forall (cp :: T) (st :: T).
(ParameterScope cp, StorageScope st) =>
AliasBehavior
-> ContractAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe KeyHash
-> Maybe Mutez
-> OriginationData
OriginationData
      { odAliasBehavior :: AliasBehavior
odAliasBehavior = AliasBehavior
lodAliasBehavior
      , odName :: ContractAlias
odName = ContractAlias
lodName
      , odBalance :: Mutez
odBalance = Mutez
lodBalance
      , odContract :: Contract (ToT cp) (ToT st)
odContract = Contract cp st vd -> Contract (ToT cp) (ToT st)
forall cp st vd. Contract cp st vd -> Contract (ToT cp) (ToT st)
L.toMichelsonContract Contract cp st vd
lodContract
      , odStorage :: Value (ToT st)
odStorage = st -> Value (ToT st)
forall a. IsoValue a => a -> Value (ToT a)
toVal st
lodStorage
      , odDelegate :: Maybe KeyHash
odDelegate = Maybe KeyHash
lodDelegate
      , odMbFee :: Maybe Mutez
odMbFee = Maybe Mutez
lodMbFee
      }

-- | Checks that the origination result for a single contract is indeed one.
singleOriginatedContract
  :: forall m. HasTezosRpc m
  => Maybe OperationHash -> [ContractAddress]
  -> m (OperationHash, ContractAddress)
singleOriginatedContract :: forall (m :: * -> *).
HasTezosRpc m =>
Maybe OperationHash
-> [ContractAddress] -> m (OperationHash, ContractAddress)
singleOriginatedContract Maybe OperationHash
mbHash [ContractAddress]
contracts = case [ContractAddress]
contracts of
  [ContractAddress
addr] -> case Maybe OperationHash
mbHash of
    Just OperationHash
hash -> (OperationHash, ContractAddress)
-> m (OperationHash, ContractAddress)
forall (m :: * -> *) a. Monad m => a -> m a
return (OperationHash
hash, ContractAddress
addr)
    Maybe OperationHash
Nothing -> IncorrectRpcResponse -> m (OperationHash, ContractAddress)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IncorrectRpcResponse -> m (OperationHash, ContractAddress))
-> IncorrectRpcResponse -> m (OperationHash, ContractAddress)
forall a b. (a -> b) -> a -> b
$ IncorrectRpcResponse
RpcOriginatedNoContracts
  [ContractAddress]
_ ->  IncorrectRpcResponse -> m (OperationHash, ContractAddress)
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM (IncorrectRpcResponse -> m (OperationHash, ContractAddress))
-> IncorrectRpcResponse -> m (OperationHash, ContractAddress)
forall a b. (a -> b) -> a -> b
$ [ContractAddress] -> IncorrectRpcResponse
RpcOriginatedMoreContracts [ContractAddress]
contracts