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

-- | Functions to originate smart contracts via @tezos-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
     )
  => Bool
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> Contract cp st
  -> Value st
  -> Maybe Mutez
  -> m (OperationHash, ContractAddress)
originateContract :: forall (m :: * -> *) (cp :: T) (st :: T) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 StorageScope st, ParameterScope cp) =>
Bool
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> m (OperationHash, ContractAddress)
originateContract Bool
odReplaceExisting ContractAlias
odName ImplicitAddressOrAlias
sender' Mutez
odBalance Contract cp st
odContract Value st
odStorage Maybe Mutez
odMbFee = 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) =>
Bool
-> ContractAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> OriginationData
OriginationData{Bool
Maybe Mutez
ContractAlias
Mutez
Contract cp st
Value st
odMbFee :: Maybe Mutez
odStorage :: Value st
odContract :: Contract cp st
odBalance :: Mutez
odName :: ContractAlias
odReplaceExisting :: Bool
odMbFee :: Maybe Mutez
odStorage :: Value st
odContract :: Contract cp st
odBalance :: Mutez
odName :: ContractAlias
odReplaceExisting :: Bool
..}]
  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
     )
  => Bool
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> U.Contract
  -> U.Value
  -> Maybe Mutez
  -> m (OperationHash, ContractAddress)
originateUntypedContract :: forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
Bool
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract
-> Value
-> Maybe Mutez
-> m (OperationHash, ContractAddress)
originateUntypedContract Bool
replaceExisting ContractAlias
name ImplicitAddressOrAlias
sender' Mutez
balance Contract
uContract Value
initialStorage Maybe Mutez
mbFee = do
  SomeContractAndStorage Contract cp st
contract Value st
storage <-
    m (Either TCError SomeContractAndStorage)
-> m SomeContractAndStorage
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
m (Either e a) -> m a
throwLeft (m (Either TCError SomeContractAndStorage)
 -> m SomeContractAndStorage)
-> (TypeCheckResult SomeContractAndStorage
    -> m (Either TCError SomeContractAndStorage))
-> TypeCheckResult SomeContractAndStorage
-> m SomeContractAndStorage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either TCError SomeContractAndStorage
-> m (Either TCError SomeContractAndStorage)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either TCError SomeContractAndStorage
 -> m (Either TCError SomeContractAndStorage))
-> (TypeCheckResult SomeContractAndStorage
    -> Either TCError SomeContractAndStorage)
-> TypeCheckResult SomeContractAndStorage
-> m (Either TCError SomeContractAndStorage)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeCheckOptions
-> TypeCheckResult SomeContractAndStorage
-> Either TCError SomeContractAndStorage
forall a. TypeCheckOptions -> TypeCheckResult a -> Either TCError a
typeCheckingWith TypeCheckOptions
forall a. Default a => a
def (TypeCheckResult SomeContractAndStorage
 -> m SomeContractAndStorage)
-> TypeCheckResult SomeContractAndStorage
-> m SomeContractAndStorage
forall a b. (a -> b) -> a -> b
$
      Contract -> Value -> TypeCheckResult SomeContractAndStorage
typeCheckContractAndStorage Contract
uContract Value
initialStorage
  Bool
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> m (OperationHash, ContractAddress)
forall (m :: * -> *) (cp :: T) (st :: T) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 StorageScope st, ParameterScope cp) =>
Bool
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> m (OperationHash, ContractAddress)
originateContract Bool
replaceExisting ContractAlias
name ImplicitAddressOrAlias
sender' Mutez
balance Contract cp st
contract Value st
storage Maybe Mutez
mbFee

-- | 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
     )
  => Bool
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> L.Contract cp st vd
  -> st
  -> Maybe Mutez
  -> m (OperationHash, ContractAddress)
lOriginateContract :: forall (m :: * -> *) cp st vd env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 NiceStorage st, NiceParameterFull cp) =>
Bool
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st vd
-> st
-> Maybe Mutez
-> m (OperationHash, ContractAddress)
lOriginateContract Bool
lodReplaceExisting ContractAlias
lodName ImplicitAddressOrAlias
sender' Mutez
lodBalance Contract cp st vd
lodContract st
lodStorage Maybe Mutez
lodMbFee = 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) =>
Bool
-> ContractAlias
-> Mutez
-> Contract cp st vd
-> st
-> Maybe Mutez
-> LOriginationData
LOriginationData{st
Bool
Maybe Mutez
ContractAlias
Mutez
Contract cp st vd
lodMbFee :: Maybe Mutez
lodStorage :: st
lodContract :: Contract cp st vd
lodBalance :: Mutez
lodName :: ContractAlias
lodReplaceExisting :: Bool
lodMbFee :: Maybe Mutez
lodStorage :: st
lodContract :: Contract cp st vd
lodBalance :: Mutez
lodName :: ContractAlias
lodReplaceExisting :: Bool
..}]
  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
  KindedAddress 'AddressKindImplicit
senderAddress <- ImplicitAddressOrAlias -> m (KindedAddress 'AddressKindImplicit)
forall (m :: * -> *) (kind :: AddressKind).
(MonadThrow m, HasTezosClient m) =>
AddressOrAlias kind -> m (KindedAddress kind)
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 (KindedAddress 'AddressKindImplicit
-> LargeOriginationData -> OriginationData
mkLargeOriginatorData KindedAddress 'AddressKindImplicit
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))
-> [TransactionData] -> m ()
forall t (m :: * -> *) b.
(Container t, Monad m) =>
(Element t -> m b) -> t -> m ()
mapM_ (KindedAddress 'AddressKindImplicit
-> [TransactionData] -> m (Maybe OperationHash)
forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
KindedAddress 'AddressKindImplicit
-> [TransactionData] -> m (Maybe OperationHash)
runTransactions KindedAddress 'AddressKindImplicit
senderAddress ([TransactionData] -> m (Maybe OperationHash))
-> (TransactionData -> [TransactionData])
-> TransactionData
-> m (Maybe OperationHash)
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
     )
  => Bool
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> Contract cp st
  -> Value st
  -> Maybe Mutez
  -> m (OperationHash, ContractAddress)
originateLargeContract :: forall (m :: * -> *) (cp :: T) (st :: T) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 StorageScope st, ParameterScope cp) =>
Bool
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> m (OperationHash, ContractAddress)
originateLargeContract Bool
odReplaceExisting ContractAlias
odName ImplicitAddressOrAlias
sender' Mutez
odBalance Contract cp st
odContract Value st
odStorage Maybe Mutez
odMbFee = 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) =>
Bool
-> ContractAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> OriginationData
OriginationData{Bool
Maybe Mutez
ContractAlias
Mutez
Contract cp st
Value st
odMbFee :: Maybe Mutez
odStorage :: Value st
odContract :: Contract cp st
odBalance :: Mutez
odName :: ContractAlias
odReplaceExisting :: Bool
odMbFee :: Maybe Mutez
odStorage :: Value st
odContract :: Contract cp st
odBalance :: Mutez
odName :: ContractAlias
odReplaceExisting :: Bool
..}]
  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
     )
  => Bool
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> U.Contract
  -> U.Value
  -> Maybe Mutez
  -> m (OperationHash, ContractAddress)
originateLargeUntypedContract :: forall (m :: * -> *) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m) =>
Bool
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract
-> Value
-> Maybe Mutez
-> m (OperationHash, ContractAddress)
originateLargeUntypedContract Bool
replaceExisting ContractAlias
name ImplicitAddressOrAlias
sender' Mutez
balance Contract
uContract Value
initialStorage Maybe Mutez
mbFee = do
  SomeContractAndStorage Contract cp st
contract Value st
storage <-
    m (Either TCError SomeContractAndStorage)
-> m SomeContractAndStorage
forall (m :: * -> *) e a.
(MonadThrow m, Exception e) =>
m (Either e a) -> m a
throwLeft (m (Either TCError SomeContractAndStorage)
 -> m SomeContractAndStorage)
-> (TypeCheckResult SomeContractAndStorage
    -> m (Either TCError SomeContractAndStorage))
-> TypeCheckResult SomeContractAndStorage
-> m SomeContractAndStorage
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either TCError SomeContractAndStorage
-> m (Either TCError SomeContractAndStorage)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either TCError SomeContractAndStorage
 -> m (Either TCError SomeContractAndStorage))
-> (TypeCheckResult SomeContractAndStorage
    -> Either TCError SomeContractAndStorage)
-> TypeCheckResult SomeContractAndStorage
-> m (Either TCError SomeContractAndStorage)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeCheckOptions
-> TypeCheckResult SomeContractAndStorage
-> Either TCError SomeContractAndStorage
forall a. TypeCheckOptions -> TypeCheckResult a -> Either TCError a
typeCheckingWith TypeCheckOptions
forall a. Default a => a
def (TypeCheckResult SomeContractAndStorage
 -> m SomeContractAndStorage)
-> TypeCheckResult SomeContractAndStorage
-> m SomeContractAndStorage
forall a b. (a -> b) -> a -> b
$
      Contract -> Value -> TypeCheckResult SomeContractAndStorage
typeCheckContractAndStorage Contract
uContract Value
initialStorage
  Bool
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> m (OperationHash, ContractAddress)
forall (m :: * -> *) (cp :: T) (st :: T) env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 StorageScope st, ParameterScope cp) =>
Bool
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> m (OperationHash, ContractAddress)
originateLargeContract Bool
replaceExisting ContractAlias
name ImplicitAddressOrAlias
sender' Mutez
balance Contract cp st
contract Value st
storage Maybe Mutez
mbFee

-- | 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
     )
  => Bool
  -> ContractAlias
  -> ImplicitAddressOrAlias
  -> Mutez
  -> L.Contract cp st vd
  -> st
  -> Maybe Mutez
  -> m (OperationHash, ContractAddress)
lOriginateLargeContract :: forall (m :: * -> *) cp st vd env.
(HasTezosRpc m, HasTezosClient m, WithClientLog env m,
 NiceStorage st, NiceParameterFull cp) =>
Bool
-> ContractAlias
-> ImplicitAddressOrAlias
-> Mutez
-> Contract cp st vd
-> st
-> Maybe Mutez
-> m (OperationHash, ContractAddress)
lOriginateLargeContract Bool
lodReplaceExisting ContractAlias
lodName ImplicitAddressOrAlias
sender' Mutez
lodBalance Contract cp st vd
lodContract st
lodStorage Maybe Mutez
lodMbFee = 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) =>
Bool
-> ContractAlias
-> Mutez
-> Contract cp st vd
-> st
-> Maybe Mutez
-> LOriginationData
LOriginationData{st
Bool
Maybe Mutez
ContractAlias
Mutez
Contract cp st vd
lodMbFee :: Maybe Mutez
lodStorage :: st
lodContract :: Contract cp st vd
lodBalance :: Mutez
lodName :: ContractAlias
lodReplaceExisting :: Bool
lodMbFee :: Maybe Mutez
lodStorage :: st
lodContract :: Contract cp st vd
lodBalance :: Mutez
lodName :: ContractAlias
lodReplaceExisting :: Bool
..}]
  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 -> Bool
lodReplaceExisting :: Bool
  , LOriginationData -> ContractAlias
lodName :: ContractAlias
  , LOriginationData -> Mutez
lodBalance :: Mutez
  , ()
lodContract :: L.Contract cp st vd
  , ()
lodStorage :: st
  , LOriginationData -> Maybe Mutez
lodMbFee :: Maybe Mutez
  }

convertLOriginationData :: LOriginationData -> OriginationData
convertLOriginationData :: LOriginationData -> OriginationData
convertLOriginationData LOriginationData {st
Bool
Maybe Mutez
ContractAlias
Mutez
Contract cp st vd
lodMbFee :: Maybe Mutez
lodStorage :: st
lodContract :: Contract cp st vd
lodBalance :: Mutez
lodName :: ContractAlias
lodReplaceExisting :: Bool
lodMbFee :: LOriginationData -> Maybe Mutez
lodStorage :: ()
lodContract :: ()
lodBalance :: LOriginationData -> Mutez
lodName :: LOriginationData -> ContractAlias
lodReplaceExisting :: LOriginationData -> Bool
..} = case Contract cp st vd
lodContract of
  (Contract cp st vd
_ :: L.Contract cp st vd) ->
    (NiceStorage st :- StorageScope (ToT st))
-> (StorageScope (ToT st) => OriginationData) -> OriginationData
forall (c :: Constraint) e r. HasDict c e => e -> (c => r) -> r
withDict (forall a. NiceStorage a :- StorageScope (ToT a)
niceStorageEvi @st) ((StorageScope (ToT st) => OriginationData) -> OriginationData)
-> (StorageScope (ToT st) => OriginationData) -> OriginationData
forall a b. (a -> b) -> a -> b
$
      (NiceParameter cp :- ParameterScope (ToT cp))
-> (ParameterScope (ToT cp) => OriginationData) -> OriginationData
forall (c :: Constraint) e r. HasDict c e => e -> (c => r) -> r
withDict (forall a. NiceParameter a :- ParameterScope (ToT a)
niceParameterEvi @cp) ((ParameterScope (ToT cp) => OriginationData) -> OriginationData)
-> (ParameterScope (ToT cp) => OriginationData) -> OriginationData
forall a b. (a -> b) -> a -> b
$ OriginationData :: forall (cp :: T) (st :: T).
(ParameterScope cp, StorageScope st) =>
Bool
-> ContractAlias
-> Mutez
-> Contract cp st
-> Value st
-> Maybe Mutez
-> OriginationData
OriginationData
        { odReplaceExisting :: Bool
odReplaceExisting = Bool
lodReplaceExisting
        , 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
        , 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