mirror of
https://github.com/FiloSpaTeam/plutus-pioneer-program.git
synced 2024-11-15 03:12:34 +01:00
120 lines
6 KiB
Haskell
120 lines
6 KiB
Haskell
|
{-# LANGUAGE DataKinds #-}
|
||
|
{-# LANGUAGE DeriveAnyClass #-}
|
||
|
{-# LANGUAGE DeriveGeneric #-}
|
||
|
{-# LANGUAGE DerivingStrategies #-}
|
||
|
{-# LANGUAGE FlexibleContexts #-}
|
||
|
{-# LANGUAGE LambdaCase #-}
|
||
|
{-# LANGUAGE OverloadedStrings #-}
|
||
|
{-# LANGUAGE RankNTypes #-}
|
||
|
{-# LANGUAGE TypeApplications #-}
|
||
|
{-# LANGUAGE TypeFamilies #-}
|
||
|
{-# LANGUAGE TypeOperators #-}
|
||
|
module Main
|
||
|
( main
|
||
|
) where
|
||
|
|
||
|
import Control.Monad (forM, void)
|
||
|
import Control.Monad.Freer (Eff, Member, interpret, type (~>))
|
||
|
import Control.Monad.Freer.Error (Error)
|
||
|
import Control.Monad.Freer.Extras.Log (LogMsg)
|
||
|
import Control.Monad.IO.Class (MonadIO (..))
|
||
|
import Data.Aeson (FromJSON, Result (..), ToJSON, encode, fromJSON)
|
||
|
import qualified Data.Map.Strict as Map
|
||
|
import qualified Data.Monoid as Monoid
|
||
|
import qualified Data.Semigroup as Semigroup
|
||
|
import Data.Text (Text)
|
||
|
import Data.Text.Prettyprint.Doc (Pretty (..), viaShow)
|
||
|
import GHC.Generics (Generic)
|
||
|
import Ledger.Ada (adaSymbol, adaToken)
|
||
|
import Plutus.Contract
|
||
|
import qualified Plutus.Contracts.Currency as Currency
|
||
|
import qualified Plutus.Contracts.Uniswap as Uniswap
|
||
|
import Plutus.PAB.Effects.Contract (ContractEffect (..))
|
||
|
import Plutus.PAB.Effects.Contract.Builtin (Builtin, SomeBuiltin (..), type (.\\))
|
||
|
import qualified Plutus.PAB.Effects.Contract.Builtin as Builtin
|
||
|
import Plutus.PAB.Monitoring.PABLogMsg (PABMultiAgentMsg)
|
||
|
import Plutus.PAB.Simulator (SimulatorEffectHandlers, logString)
|
||
|
import qualified Plutus.PAB.Simulator as Simulator
|
||
|
import Plutus.PAB.Types (PABError (..))
|
||
|
import qualified Plutus.PAB.Webserver.Server as PAB.Server
|
||
|
import Prelude hiding (init)
|
||
|
import Uniswap as US
|
||
|
import Wallet.Emulator.Types (Wallet (..))
|
||
|
|
||
|
main :: IO ()
|
||
|
main = void $ Simulator.runSimulationWith handlers $ do
|
||
|
logString @(Builtin UniswapContracts) "Starting Uniswap PAB webserver on port 8080. Press enter to exit."
|
||
|
shutdown <- PAB.Server.startServerDebug
|
||
|
|
||
|
cidInit <- Simulator.activateContract (Wallet 1) Init
|
||
|
cs <- flip Simulator.waitForState cidInit $ \json -> case fromJSON json of
|
||
|
Success (Just (Semigroup.Last cur)) -> Just $ Currency.currencySymbol cur
|
||
|
_ -> Nothing
|
||
|
_ <- Simulator.waitUntilFinished cidInit
|
||
|
|
||
|
logString @(Builtin UniswapContracts) $ "Initialization finished. Minted: " ++ show cs
|
||
|
|
||
|
let coins = Map.fromList [(tn, Uniswap.mkCoin cs tn) | tn <- tokenNames]
|
||
|
ada = Uniswap.mkCoin adaSymbol adaToken
|
||
|
|
||
|
cidStart <- Simulator.activateContract (Wallet 1) UniswapStart
|
||
|
us <- flip Simulator.waitForState cidStart $ \json -> case (fromJSON json :: Result (Monoid.Last (Either Text Uniswap.Uniswap))) of
|
||
|
Success (Monoid.Last (Just (Right us))) -> Just us
|
||
|
_ -> Nothing
|
||
|
logString @(Builtin UniswapContracts) $ "Uniswap instance created: " ++ show us
|
||
|
|
||
|
cids <- fmap Map.fromList $ forM wallets $ \w -> do
|
||
|
cid <- Simulator.activateContract w $ UniswapUser us
|
||
|
logString @(Builtin UniswapContracts) $ "Uniswap user contract started for " ++ show w
|
||
|
Simulator.waitForEndpoint cid "funds"
|
||
|
_ <- Simulator.callEndpointOnInstance cid "funds" ()
|
||
|
v <- flip Simulator.waitForState cid $ \json -> case (fromJSON json :: Result (Monoid.Last (Either Text Uniswap.UserContractState))) of
|
||
|
Success (Monoid.Last (Just (Right (Uniswap.Funds v)))) -> Just v
|
||
|
_ -> Nothing
|
||
|
logString @(Builtin UniswapContracts) $ "initial funds in wallet " ++ show w ++ ": " ++ show v
|
||
|
return (w, cid)
|
||
|
|
||
|
let cp = Uniswap.CreateParams ada (coins Map.! "A") 100000 500000
|
||
|
logString @(Builtin UniswapContracts) $ "creating liquidity pool: " ++ show (encode cp)
|
||
|
let cid2 = cids Map.! Wallet 2
|
||
|
Simulator.waitForEndpoint cid2 "create"
|
||
|
_ <- Simulator.callEndpointOnInstance cid2 "create" cp
|
||
|
flip Simulator.waitForState (cids Map.! Wallet 2) $ \json -> case (fromJSON json :: Result (Monoid.Last (Either Text Uniswap.UserContractState))) of
|
||
|
Success (Monoid.Last (Just (Right Uniswap.Created))) -> Just ()
|
||
|
_ -> Nothing
|
||
|
logString @(Builtin UniswapContracts) "liquidity pool created"
|
||
|
|
||
|
_ <- liftIO getLine
|
||
|
shutdown
|
||
|
|
||
|
data UniswapContracts =
|
||
|
Init
|
||
|
| UniswapStart
|
||
|
| UniswapUser Uniswap.Uniswap
|
||
|
deriving (Eq, Ord, Show, Generic)
|
||
|
deriving anyclass (FromJSON, ToJSON)
|
||
|
|
||
|
instance Pretty UniswapContracts where
|
||
|
pretty = viaShow
|
||
|
|
||
|
handleUniswapContract ::
|
||
|
( Member (Error PABError) effs
|
||
|
, Member (LogMsg (PABMultiAgentMsg (Builtin UniswapContracts))) effs
|
||
|
)
|
||
|
=> ContractEffect (Builtin UniswapContracts)
|
||
|
~> Eff effs
|
||
|
handleUniswapContract = Builtin.handleBuiltin getSchema getContract where
|
||
|
getSchema = \case
|
||
|
UniswapUser _ -> Builtin.endpointsToSchemas @(Uniswap.UniswapUserSchema .\\ BlockchainActions)
|
||
|
UniswapStart -> Builtin.endpointsToSchemas @(Uniswap.UniswapOwnerSchema .\\ BlockchainActions)
|
||
|
Init -> Builtin.endpointsToSchemas @Empty
|
||
|
getContract = \case
|
||
|
UniswapUser us -> SomeBuiltin $ Uniswap.userEndpoints us
|
||
|
UniswapStart -> SomeBuiltin Uniswap.ownerEndpoint
|
||
|
Init -> SomeBuiltin US.initContract
|
||
|
|
||
|
handlers :: SimulatorEffectHandlers (Builtin UniswapContracts)
|
||
|
handlers =
|
||
|
Simulator.mkSimulatorHandlers @(Builtin UniswapContracts) [] -- [Init, UniswapStart, UniswapUser ???]
|
||
|
$ interpret handleUniswapContract
|