restructure agora-scripts modules
In order to allow reusing this code in the future, I've made it so that Agora-specific code all lives in `Main`, and everything else lives in `ScriptExport` or other non-Agora modules.
This commit is contained in:
parent
c7869fe701
commit
a7ed7989f1
10 changed files with 345 additions and 267 deletions
|
|
@ -1,144 +0,0 @@
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
|
||||||
|
|
||||||
{- | Module : API
|
|
||||||
Maintainer : emi@haskell.fyi
|
|
||||||
Description: API for script exporter.
|
|
||||||
|
|
||||||
API for script exporter.
|
|
||||||
-}
|
|
||||||
module API (
|
|
||||||
AgoraScripts (..),
|
|
||||||
ScriptParams (..),
|
|
||||||
API,
|
|
||||||
agoraScripts,
|
|
||||||
runServer,
|
|
||||||
) where
|
|
||||||
|
|
||||||
import Agora.AuthorityToken (AuthorityToken (..), authorityTokenPolicy)
|
|
||||||
import Agora.Governor (Governor (..))
|
|
||||||
import Agora.Governor qualified as Governor
|
|
||||||
import Agora.Governor.Scripts (authorityTokenFromGovernor, authorityTokenSymbolFromGovernor, governorPolicy, governorValidator, proposalFromGovernor, stakeFromGovernor)
|
|
||||||
import Agora.Proposal (Proposal (..))
|
|
||||||
import Agora.Proposal.Scripts (proposalPolicy, proposalValidator)
|
|
||||||
import Agora.ScriptInfo (mkPolicyInfo, mkValidatorInfo)
|
|
||||||
import Agora.Stake (Stake (..))
|
|
||||||
import Agora.Stake.Scripts (stakePolicy, stakeValidator)
|
|
||||||
import Agora.Treasury (treasuryValidator)
|
|
||||||
import Codec.Serialise.Orphans ()
|
|
||||||
import Data.Aeson qualified as Aeson
|
|
||||||
import Data.Cache.Cached (cachedFor)
|
|
||||||
import Data.Default.Class (Default (def))
|
|
||||||
import Data.Function ((&))
|
|
||||||
import Data.Proxy (Proxy (Proxy))
|
|
||||||
import Development.GitRev (gitBranch, gitHash)
|
|
||||||
import Network.HTTP.Types qualified as Http
|
|
||||||
import Network.Wai qualified as Wai
|
|
||||||
import Network.Wai.Handler.Warp qualified as Warp
|
|
||||||
import Network.Wai.Middleware.Cors (CorsResourcePolicy (corsRequestHeaders), cors, simpleCorsResourcePolicy)
|
|
||||||
import Options (Options (..))
|
|
||||||
import Plutarch.Api.V1 (mintingPolicySymbol, mkMintingPolicy)
|
|
||||||
import PlutusLedgerApi.V1.Value (AssetClass, CurrencySymbol)
|
|
||||||
import PlutusLedgerApi.V1.Value qualified as Value
|
|
||||||
import Prettyprinter (defaultLayoutOptions, hsep, layoutPretty, viaShow, (<+>))
|
|
||||||
import Prettyprinter.Render.String (renderString)
|
|
||||||
import Servant.API (JSON, Post, ReqBody, (:<|>) (..), type (:>))
|
|
||||||
import Servant.Server qualified as Servant
|
|
||||||
import System.Clock (TimeSpec (TimeSpec))
|
|
||||||
import Text.Printf (printf)
|
|
||||||
import Types (AgoraScripts (..), Builders, ScriptParams (..), ScriptQuery, insertBuilder, runQuery)
|
|
||||||
|
|
||||||
-- | Servant API type for script generation.
|
|
||||||
type API =
|
|
||||||
"generate-scripts" :> ReqBody '[JSON] ScriptParams :> Post '[JSON] AgoraScripts
|
|
||||||
:<|> "query-script" :> ReqBody '[JSON] ScriptQuery :> Post '[JSON] Aeson.Value
|
|
||||||
|
|
||||||
-- | Run a Warp server that exposes a script generation endpoint.
|
|
||||||
runServer :: Options -> IO ()
|
|
||||||
runServer options = do
|
|
||||||
let settings =
|
|
||||||
Warp.defaultSettings
|
|
||||||
& Warp.setPort options.port
|
|
||||||
& Warp.setLogger
|
|
||||||
( \req status _maybeFileSize ->
|
|
||||||
putStrLn . renderString . layoutPretty defaultLayoutOptions $
|
|
||||||
hsep
|
|
||||||
[ "[info]"
|
|
||||||
, "[" <> "Status:" <+> viaShow (Http.statusCode status) <> "]"
|
|
||||||
, viaShow $ Wai.requestMethod req
|
|
||||||
, viaShow $ Wai.rawPathInfo req
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
corsPolicy =
|
|
||||||
simpleCorsResourcePolicy
|
|
||||||
{ -- NOTE: Webpack dev server requires this for CORS workaround.
|
|
||||||
corsRequestHeaders = "content-type" : corsRequestHeaders simpleCorsResourcePolicy
|
|
||||||
}
|
|
||||||
corsMiddleware = cors . const $ Just corsPolicy
|
|
||||||
|
|
||||||
-- Scripts stay cached for five minutes
|
|
||||||
agoraScripts' <- cachedFor (Just $ TimeSpec 300 0) agoraScripts
|
|
||||||
query <- cachedFor (Just $ TimeSpec 300 0) (`runQuery` agoraBuilders)
|
|
||||||
|
|
||||||
printf "[info] Running 'agora-scripts' on :%d\n" (Warp.getPort settings)
|
|
||||||
Servant.serve
|
|
||||||
(Proxy @API)
|
|
||||||
(agoraScripts' :<|> query)
|
|
||||||
& corsMiddleware
|
|
||||||
& Warp.runSettings settings
|
|
||||||
|
|
||||||
agoraBuilders :: Builders
|
|
||||||
agoraBuilders =
|
|
||||||
def
|
|
||||||
& insertBuilder "governorPolicy" ((.governorPolicyInfo) . agoraScripts)
|
|
||||||
& insertBuilder "governorValidator" ((.governorValidatorInfo) . agoraScripts)
|
|
||||||
& insertBuilder "stakePolicyInfo" ((.stakePolicyInfo) . agoraScripts)
|
|
||||||
& insertBuilder "stakeValidatorInfo" ((.stakeValidatorInfo) . agoraScripts)
|
|
||||||
& insertBuilder "proposalPolicyInfo" ((.proposalPolicyInfo) . agoraScripts)
|
|
||||||
& insertBuilder "proposalValidatorInfo" ((.proposalValidatorInfo) . agoraScripts)
|
|
||||||
& insertBuilder "treasuryValidatorInfo" ((.treasuryValidatorInfo) . agoraScripts)
|
|
||||||
& insertBuilder "authorityTokenPolicyInfo" ((.authorityTokenPolicyInfo) . agoraScripts)
|
|
||||||
|
|
||||||
-- | Create scripts from params.
|
|
||||||
agoraScripts :: ScriptParams -> AgoraScripts
|
|
||||||
agoraScripts params =
|
|
||||||
AgoraScripts
|
|
||||||
{ gitRev = revision
|
|
||||||
, governorPolicyInfo = mkPolicyInfo (governorPolicy governor)
|
|
||||||
, governorValidatorInfo = mkValidatorInfo (governorValidator governor)
|
|
||||||
, stakePolicyInfo = mkPolicyInfo (stakePolicy params.gtClassRef)
|
|
||||||
, stakeValidatorInfo = mkValidatorInfo (stakeValidator stake)
|
|
||||||
, proposalPolicyInfo = mkPolicyInfo (proposalPolicy governorSTAssetClass)
|
|
||||||
, proposalValidatorInfo = mkValidatorInfo (proposalValidator proposal)
|
|
||||||
, treasuryValidatorInfo = mkValidatorInfo (treasuryValidator authorityTokenSymbol)
|
|
||||||
, authorityTokenPolicyInfo = mkPolicyInfo (authorityTokenPolicy authorityToken)
|
|
||||||
}
|
|
||||||
where
|
|
||||||
-- This encodes the git revision of the server. It's useful for the caller
|
|
||||||
-- to be able to ensure they are compatible with it.
|
|
||||||
revision :: String
|
|
||||||
revision = $(gitBranch) <> "@" <> $(gitHash)
|
|
||||||
|
|
||||||
governor :: Governor
|
|
||||||
governor =
|
|
||||||
Governor
|
|
||||||
{ Governor.gstOutRef = params.governorInitialSpend
|
|
||||||
, Governor.gtClassRef = params.gtClassRef
|
|
||||||
, Governor.maximumCosigners = params.maximumCosigners
|
|
||||||
}
|
|
||||||
|
|
||||||
authorityToken :: AuthorityToken
|
|
||||||
authorityToken = authorityTokenFromGovernor governor
|
|
||||||
|
|
||||||
authorityTokenSymbol :: CurrencySymbol
|
|
||||||
authorityTokenSymbol = authorityTokenSymbolFromGovernor governor
|
|
||||||
|
|
||||||
governorSTAssetClass :: AssetClass
|
|
||||||
governorSTAssetClass =
|
|
||||||
Value.assetClass (mintingPolicySymbol $ mkMintingPolicy $ governorPolicy governor) ""
|
|
||||||
|
|
||||||
proposal :: Proposal
|
|
||||||
proposal = proposalFromGovernor governor
|
|
||||||
|
|
||||||
stake :: Stake
|
|
||||||
stake = stakeFromGovernor governor
|
|
||||||
|
|
@ -9,12 +9,10 @@ Orphan instances for Serialising and Hashing Cardano types.
|
||||||
-}
|
-}
|
||||||
module Codec.Serialise.Orphans () where
|
module Codec.Serialise.Orphans () where
|
||||||
|
|
||||||
import Codec.Serialise (Serialise, serialise)
|
import Codec.Serialise (Serialise)
|
||||||
import Data.Hashable (Hashable (hashWithSalt))
|
|
||||||
import Data.Tagged (Tagged (Tagged))
|
import Data.Tagged (Tagged (Tagged))
|
||||||
import PlutusLedgerApi.V1 (TxId, TxOutRef)
|
import PlutusLedgerApi.V1 (TxId, TxOutRef)
|
||||||
import PlutusLedgerApi.V1.Value (AssetClass, CurrencySymbol, TokenName)
|
import PlutusLedgerApi.V1.Value (AssetClass, CurrencySymbol, TokenName)
|
||||||
import Types (ScriptParams)
|
|
||||||
|
|
||||||
deriving anyclass instance
|
deriving anyclass instance
|
||||||
Serialise TxOutRef
|
Serialise TxOutRef
|
||||||
|
|
@ -34,8 +32,3 @@ deriving anyclass instance
|
||||||
deriving newtype instance
|
deriving newtype instance
|
||||||
Serialise a =>
|
Serialise a =>
|
||||||
Serialise (Tagged s a)
|
Serialise (Tagged s a)
|
||||||
|
|
||||||
deriving anyclass instance Serialise ScriptParams
|
|
||||||
|
|
||||||
instance Hashable ScriptParams where
|
|
||||||
hashWithSalt s scriptParams = hashWithSalt s (serialise scriptParams)
|
|
||||||
|
|
|
||||||
144
agora-scripts/Main.hs
Normal file
144
agora-scripts/Main.hs
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
|
||||||
|
{- | Module : Main
|
||||||
|
Maintainer : emi@haskell.fyi
|
||||||
|
Description: Export scripts given configuration.
|
||||||
|
|
||||||
|
Export scripts given configuration.
|
||||||
|
-}
|
||||||
|
module Main (main) where
|
||||||
|
|
||||||
|
import Agora.AuthorityToken (AuthorityToken, authorityTokenPolicy)
|
||||||
|
import Agora.Governor (Governor (Governor))
|
||||||
|
import Agora.Governor qualified as Governor
|
||||||
|
import Agora.Governor.Scripts (authorityTokenFromGovernor, authorityTokenSymbolFromGovernor, governorPolicy, governorValidator, proposalFromGovernor, stakeFromGovernor)
|
||||||
|
import Agora.Proposal (Proposal)
|
||||||
|
import Agora.Proposal.Scripts (proposalPolicy, proposalValidator)
|
||||||
|
import Agora.SafeMoney (GTTag)
|
||||||
|
import Agora.ScriptInfo (PolicyInfo, ValidatorInfo, mkPolicyInfo, mkValidatorInfo)
|
||||||
|
import Agora.Stake (Stake)
|
||||||
|
import Agora.Stake.Scripts (stakePolicy, stakeValidator)
|
||||||
|
import Agora.Treasury (treasuryValidator)
|
||||||
|
import Data.Aeson qualified as Aeson
|
||||||
|
import Data.Default (def)
|
||||||
|
import Data.Function ((&))
|
||||||
|
import Data.Tagged (Tagged)
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Development.GitRev (gitBranch, gitHash)
|
||||||
|
import GHC.Generics qualified as GHC
|
||||||
|
import Plutarch.Api.V1 (mintingPolicySymbol, mkMintingPolicy)
|
||||||
|
import PlutusLedgerApi.V1 (TxOutRef)
|
||||||
|
import PlutusLedgerApi.V1.Value (AssetClass, CurrencySymbol)
|
||||||
|
import PlutusLedgerApi.V1.Value qualified as Value
|
||||||
|
import ScriptExport.API (runServer)
|
||||||
|
import ScriptExport.Options (parseOptions)
|
||||||
|
import ScriptExport.Types (Builders, insertBuilder)
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main =
|
||||||
|
parseOptions >>= runServer revision builders
|
||||||
|
where
|
||||||
|
-- This encodes the git revision of the server. It's useful for the caller
|
||||||
|
-- to be able to ensure they are compatible with it.
|
||||||
|
revision :: Text
|
||||||
|
revision = $(gitBranch) <> "@" <> $(gitHash)
|
||||||
|
|
||||||
|
{- | Builders for Agora scripts.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
builders :: Builders
|
||||||
|
builders =
|
||||||
|
def
|
||||||
|
& insertBuilder "governorPolicy" ((.governorPolicyInfo) . agoraScripts)
|
||||||
|
& insertBuilder "governorValidator" ((.governorValidatorInfo) . agoraScripts)
|
||||||
|
& insertBuilder "stakePolicyInfo" ((.stakePolicyInfo) . agoraScripts)
|
||||||
|
& insertBuilder "stakeValidatorInfo" ((.stakeValidatorInfo) . agoraScripts)
|
||||||
|
& insertBuilder "proposalPolicyInfo" ((.proposalPolicyInfo) . agoraScripts)
|
||||||
|
& insertBuilder "proposalValidatorInfo" ((.proposalValidatorInfo) . agoraScripts)
|
||||||
|
& insertBuilder "treasuryValidatorInfo" ((.treasuryValidatorInfo) . agoraScripts)
|
||||||
|
& insertBuilder "authorityTokenPolicyInfo" ((.authorityTokenPolicyInfo) . agoraScripts)
|
||||||
|
|
||||||
|
{- | Create scripts from params.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
agoraScripts :: ScriptParams -> AgoraScripts
|
||||||
|
agoraScripts params =
|
||||||
|
AgoraScripts
|
||||||
|
{ governorPolicyInfo = mkPolicyInfo (governorPolicy governor)
|
||||||
|
, governorValidatorInfo = mkValidatorInfo (governorValidator governor)
|
||||||
|
, stakePolicyInfo = mkPolicyInfo (stakePolicy params.gtClassRef)
|
||||||
|
, stakeValidatorInfo = mkValidatorInfo (stakeValidator stake)
|
||||||
|
, proposalPolicyInfo = mkPolicyInfo (proposalPolicy governorSTAssetClass)
|
||||||
|
, proposalValidatorInfo = mkValidatorInfo (proposalValidator proposal)
|
||||||
|
, treasuryValidatorInfo = mkValidatorInfo (treasuryValidator authorityTokenSymbol)
|
||||||
|
, authorityTokenPolicyInfo = mkPolicyInfo (authorityTokenPolicy authorityToken)
|
||||||
|
}
|
||||||
|
where
|
||||||
|
governor :: Governor
|
||||||
|
governor =
|
||||||
|
Governor
|
||||||
|
{ Governor.gstOutRef = params.governorInitialSpend
|
||||||
|
, Governor.gtClassRef = params.gtClassRef
|
||||||
|
, Governor.maximumCosigners = params.maximumCosigners
|
||||||
|
}
|
||||||
|
|
||||||
|
authorityToken :: AuthorityToken
|
||||||
|
authorityToken = authorityTokenFromGovernor governor
|
||||||
|
|
||||||
|
authorityTokenSymbol :: CurrencySymbol
|
||||||
|
authorityTokenSymbol = authorityTokenSymbolFromGovernor governor
|
||||||
|
|
||||||
|
governorSTAssetClass :: AssetClass
|
||||||
|
governorSTAssetClass =
|
||||||
|
Value.assetClass (mintingPolicySymbol $ mkMintingPolicy $ governorPolicy governor) ""
|
||||||
|
|
||||||
|
proposal :: Proposal
|
||||||
|
proposal = proposalFromGovernor governor
|
||||||
|
|
||||||
|
stake :: Stake
|
||||||
|
stake = stakeFromGovernor governor
|
||||||
|
|
||||||
|
{- | Params required for creating script export.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
data ScriptParams where
|
||||||
|
ScriptParams ::
|
||||||
|
{ governorInitialSpend :: TxOutRef
|
||||||
|
, gtClassRef :: Tagged GTTag AssetClass
|
||||||
|
, maximumCosigners :: Integer
|
||||||
|
} ->
|
||||||
|
ScriptParams
|
||||||
|
deriving anyclass (Aeson.ToJSON, Aeson.FromJSON)
|
||||||
|
deriving stock (Show, Eq, GHC.Generic, Ord)
|
||||||
|
|
||||||
|
{- | Scripts that get exported.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
data AgoraScripts = AgoraScripts
|
||||||
|
{ governorPolicyInfo :: PolicyInfo
|
||||||
|
, governorValidatorInfo :: ValidatorInfo
|
||||||
|
, stakePolicyInfo :: PolicyInfo
|
||||||
|
, stakeValidatorInfo :: ValidatorInfo
|
||||||
|
, proposalPolicyInfo :: PolicyInfo
|
||||||
|
, proposalValidatorInfo :: ValidatorInfo
|
||||||
|
, treasuryValidatorInfo :: ValidatorInfo
|
||||||
|
, authorityTokenPolicyInfo :: PolicyInfo
|
||||||
|
}
|
||||||
|
deriving anyclass
|
||||||
|
( -- | @since 0.2.0
|
||||||
|
Aeson.ToJSON
|
||||||
|
, -- | @since 0.2.0
|
||||||
|
Aeson.FromJSON
|
||||||
|
)
|
||||||
|
deriving stock
|
||||||
|
( -- | @since 0.2.0
|
||||||
|
Show
|
||||||
|
, -- | @since 0.2.0
|
||||||
|
Eq
|
||||||
|
, -- | @since 0.2.0
|
||||||
|
GHC.Generic
|
||||||
|
)
|
||||||
100
agora-scripts/ScriptExport/API.hs
Normal file
100
agora-scripts/ScriptExport/API.hs
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
{- | Module : ScriptExport.API
|
||||||
|
Maintainer : emi@haskell.fyi
|
||||||
|
Description: API for script exporter.
|
||||||
|
|
||||||
|
API for script exporter.
|
||||||
|
-}
|
||||||
|
module ScriptExport.API (
|
||||||
|
API,
|
||||||
|
runServer,
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Codec.Serialise.Orphans ()
|
||||||
|
import Data.Aeson qualified as Aeson
|
||||||
|
import Data.Cache.Cached (cachedFor)
|
||||||
|
import Data.Function ((&))
|
||||||
|
import Data.Proxy (Proxy (Proxy))
|
||||||
|
import Data.Text (Text)
|
||||||
|
import GHC.Generics qualified as GHC
|
||||||
|
import Network.HTTP.Types qualified as Http
|
||||||
|
import Network.Wai qualified as Wai
|
||||||
|
import Network.Wai.Handler.Warp qualified as Warp
|
||||||
|
import Network.Wai.Middleware.Cors (CorsResourcePolicy (corsRequestHeaders), cors, simpleCorsResourcePolicy)
|
||||||
|
import Prettyprinter (Pretty (pretty), defaultLayoutOptions, hsep, layoutPretty, viaShow)
|
||||||
|
import Prettyprinter.Render.String (renderString)
|
||||||
|
import ScriptExport.Options (Options (..))
|
||||||
|
import ScriptExport.Types (Builders, ScriptQuery, runQuery)
|
||||||
|
import ScriptExport.Types qualified as Builders
|
||||||
|
import Servant.API (Get, JSON, Post, ReqBody, (:<|>) (..), type (:>))
|
||||||
|
import Servant.Server qualified as Servant
|
||||||
|
import System.Clock (TimeSpec (TimeSpec))
|
||||||
|
import Text.Printf (printf)
|
||||||
|
|
||||||
|
{- | Servant API type for script generation.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
type API =
|
||||||
|
"query-script" :> ReqBody '[JSON] ScriptQuery :> Post '[JSON] Aeson.Value
|
||||||
|
:<|> "info" :> Get '[JSON] ServerInfo
|
||||||
|
|
||||||
|
{- | Information about the server.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
data ServerInfo = ServerInfo
|
||||||
|
{ revision :: Text
|
||||||
|
, exposedBuilders :: [Text]
|
||||||
|
}
|
||||||
|
deriving anyclass
|
||||||
|
( -- | @since 0.2.0
|
||||||
|
Aeson.ToJSON
|
||||||
|
, -- | @since 0.2.0
|
||||||
|
Aeson.FromJSON
|
||||||
|
)
|
||||||
|
deriving stock
|
||||||
|
( -- | @since 0.2.0
|
||||||
|
Show
|
||||||
|
, -- | @since 0.2.0
|
||||||
|
Eq
|
||||||
|
, -- | @since 0.2.0
|
||||||
|
GHC.Generic
|
||||||
|
)
|
||||||
|
|
||||||
|
-- | Run a Warp server that exposes a script generation endpoint.
|
||||||
|
runServer :: Text -> Builders -> Options -> IO ()
|
||||||
|
runServer revision builders options = do
|
||||||
|
let settings =
|
||||||
|
Warp.defaultSettings
|
||||||
|
& Warp.setPort options.port
|
||||||
|
& Warp.setLogger
|
||||||
|
( \req status _maybeFileSize ->
|
||||||
|
putStrLn . renderString . layoutPretty defaultLayoutOptions $
|
||||||
|
hsep
|
||||||
|
[ "[info]"
|
||||||
|
, viaShow $ Wai.requestMethod req
|
||||||
|
, viaShow $ Wai.rawPathInfo req
|
||||||
|
, "(" <> pretty (Http.statusCode status) <> ")"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
corsPolicy =
|
||||||
|
simpleCorsResourcePolicy
|
||||||
|
{ -- NOTE: Webpack dev server requires this for CORS workaround.
|
||||||
|
corsRequestHeaders = "content-type" : corsRequestHeaders simpleCorsResourcePolicy
|
||||||
|
}
|
||||||
|
corsMiddleware = cors . const $ Just corsPolicy
|
||||||
|
|
||||||
|
-- Scripts stay cached for five minutes
|
||||||
|
query <- cachedFor (Just $ TimeSpec 300 0) (`runQuery` builders)
|
||||||
|
|
||||||
|
let serverInfo =
|
||||||
|
ServerInfo
|
||||||
|
{ revision = revision
|
||||||
|
, exposedBuilders = Builders.toList builders
|
||||||
|
}
|
||||||
|
|
||||||
|
printf "[info] Running 'agora-scripts' on :%d\n" (Warp.getPort settings)
|
||||||
|
Servant.serve (Proxy @API) (query :<|> pure serverInfo)
|
||||||
|
& corsMiddleware
|
||||||
|
& Warp.runSettings settings
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
{- |
|
{- |
|
||||||
Module : Options
|
Module : ScriptExport.Options
|
||||||
Maintainer : emi@haskell.fyi
|
Maintainer : emi@haskell.fyi
|
||||||
Description: Command line options for 'agora-scripts'.
|
Description: Command line options for 'agora-scripts'.
|
||||||
|
|
||||||
Command line options for 'agora-scripts'.
|
Command line options for 'agora-scripts'.
|
||||||
-}
|
-}
|
||||||
module Options (Options (..), parseOptions) where
|
module ScriptExport.Options (Options (..), parseOptions) where
|
||||||
|
|
||||||
import Network.Wai.Handler.Warp qualified as Warp
|
import Network.Wai.Handler.Warp qualified as Warp
|
||||||
import Options.Applicative ((<**>))
|
import Options.Applicative ((<**>))
|
||||||
94
agora-scripts/ScriptExport/Types.hs
Normal file
94
agora-scripts/ScriptExport/Types.hs
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
{- |
|
||||||
|
Module : ScriptExport.Types
|
||||||
|
Maintainer : emi@haskell.fyi
|
||||||
|
Description: Param and script types for generation.
|
||||||
|
|
||||||
|
Param and script types for generation.
|
||||||
|
-}
|
||||||
|
module ScriptExport.Types (
|
||||||
|
ScriptQuery (..),
|
||||||
|
Builders,
|
||||||
|
runQuery,
|
||||||
|
insertBuilder,
|
||||||
|
toList,
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Data.Aeson qualified as Aeson
|
||||||
|
import Data.Coerce (coerce)
|
||||||
|
import Data.Default.Class (Default (def))
|
||||||
|
import Data.Hashable (Hashable)
|
||||||
|
import Data.Map.Strict (Map)
|
||||||
|
import Data.Map.Strict qualified as Map
|
||||||
|
import Data.Text (Text)
|
||||||
|
import GHC.Generics qualified as GHC
|
||||||
|
|
||||||
|
{- | Query data for getting script info.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
data ScriptQuery = ScriptQuery
|
||||||
|
{ name :: Text
|
||||||
|
, paramsPayload :: Aeson.Value
|
||||||
|
}
|
||||||
|
deriving anyclass
|
||||||
|
( -- | @since 0.2.0
|
||||||
|
Aeson.ToJSON
|
||||||
|
, -- | @since 0.2.0
|
||||||
|
Aeson.FromJSON
|
||||||
|
)
|
||||||
|
deriving stock
|
||||||
|
( -- | @since 0.2.0
|
||||||
|
Show
|
||||||
|
, -- | @since 0.2.0
|
||||||
|
Eq
|
||||||
|
, -- | @since 0.2.0
|
||||||
|
GHC.Generic
|
||||||
|
, -- | @since 0.2.0
|
||||||
|
Ord
|
||||||
|
)
|
||||||
|
deriving anyclass
|
||||||
|
( -- | @since 0.2.0
|
||||||
|
Hashable
|
||||||
|
)
|
||||||
|
|
||||||
|
{- | Run a query on Builders.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
runQuery :: ScriptQuery -> Builders -> Aeson.Value
|
||||||
|
runQuery s =
|
||||||
|
maybe Aeson.Null ($ s.paramsPayload) . Map.lookup s.name . getBuilders
|
||||||
|
|
||||||
|
{- | Represents a list of named pure functions.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
newtype Builders = Builders
|
||||||
|
{ getBuilders :: Map Text (Aeson.Value -> Aeson.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
-- | @since 0.2.0
|
||||||
|
instance Default Builders where
|
||||||
|
def = Builders Map.empty
|
||||||
|
|
||||||
|
{- | Insert a pure function into the Builders map.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
insertBuilder ::
|
||||||
|
forall p s.
|
||||||
|
(Aeson.FromJSON p, Aeson.ToJSON s) =>
|
||||||
|
Text ->
|
||||||
|
(p -> s) ->
|
||||||
|
Builders ->
|
||||||
|
Builders
|
||||||
|
insertBuilder k = coerce . Map.insert k . throughJSON
|
||||||
|
where
|
||||||
|
throughJSON f = Aeson.toJSON . \case { Aeson.Error _ -> Nothing; Aeson.Success v -> Just (f v) } . Aeson.fromJSON
|
||||||
|
|
||||||
|
{- | Get a list of the available builders.
|
||||||
|
|
||||||
|
@since 0.2.0
|
||||||
|
-}
|
||||||
|
toList :: Builders -> [Text]
|
||||||
|
toList = Map.keys . getBuilders
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
{- | Module : Scripts
|
|
||||||
Maintainer : emi@haskell.fyi
|
|
||||||
Description: Export scripts given configuration.
|
|
||||||
|
|
||||||
Export scripts given configuration.
|
|
||||||
-}
|
|
||||||
module Scripts (main) where
|
|
||||||
|
|
||||||
import API (runServer)
|
|
||||||
import Options (parseOptions)
|
|
||||||
|
|
||||||
main :: IO ()
|
|
||||||
main =
|
|
||||||
parseOptions >>= runServer
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
{- |
|
|
||||||
Module : Types
|
|
||||||
Maintainer : emi@haskell.fyi
|
|
||||||
Description: Param and script types for generation.
|
|
||||||
|
|
||||||
Param and script types for generation.
|
|
||||||
-}
|
|
||||||
module Types (
|
|
||||||
ScriptParams (..),
|
|
||||||
AgoraScripts (..),
|
|
||||||
ScriptQuery (..),
|
|
||||||
Builders (..),
|
|
||||||
throughJSON,
|
|
||||||
runQuery,
|
|
||||||
insertBuilder,
|
|
||||||
) where
|
|
||||||
|
|
||||||
import Agora.SafeMoney (GTTag)
|
|
||||||
import Agora.ScriptInfo (PolicyInfo, ValidatorInfo)
|
|
||||||
import Data.Aeson qualified as Aeson
|
|
||||||
import Data.Coerce (coerce)
|
|
||||||
import Data.Default.Class (Default (def))
|
|
||||||
import Data.Hashable (Hashable)
|
|
||||||
import Data.Map.Strict (Map)
|
|
||||||
import Data.Map.Strict qualified as Map
|
|
||||||
import Data.Tagged (Tagged)
|
|
||||||
import Data.Text (Text)
|
|
||||||
import GHC.Generics qualified as GHC
|
|
||||||
import PlutusLedgerApi.V1 (TxOutRef)
|
|
||||||
import PlutusLedgerApi.V1.Value (AssetClass)
|
|
||||||
|
|
||||||
-- | Params required for creating script export.
|
|
||||||
data ScriptParams where
|
|
||||||
ScriptParams ::
|
|
||||||
{ governorInitialSpend :: TxOutRef
|
|
||||||
, gtClassRef :: Tagged GTTag AssetClass
|
|
||||||
, maximumCosigners :: Integer
|
|
||||||
} ->
|
|
||||||
ScriptParams
|
|
||||||
deriving anyclass (Aeson.ToJSON, Aeson.FromJSON)
|
|
||||||
deriving stock (Show, Eq, GHC.Generic, Ord)
|
|
||||||
|
|
||||||
-- | Scripts that get exported.
|
|
||||||
data AgoraScripts = AgoraScripts
|
|
||||||
{ gitRev :: String
|
|
||||||
, governorPolicyInfo :: PolicyInfo
|
|
||||||
, governorValidatorInfo :: ValidatorInfo
|
|
||||||
, stakePolicyInfo :: PolicyInfo
|
|
||||||
, stakeValidatorInfo :: ValidatorInfo
|
|
||||||
, proposalPolicyInfo :: PolicyInfo
|
|
||||||
, proposalValidatorInfo :: ValidatorInfo
|
|
||||||
, treasuryValidatorInfo :: ValidatorInfo
|
|
||||||
, authorityTokenPolicyInfo :: PolicyInfo
|
|
||||||
}
|
|
||||||
deriving anyclass (Aeson.ToJSON, Aeson.FromJSON)
|
|
||||||
deriving stock (Show, Eq, GHC.Generic)
|
|
||||||
|
|
||||||
data ScriptQuery = ScriptQuery
|
|
||||||
{ name :: Text
|
|
||||||
, paramsPayload :: Aeson.Value
|
|
||||||
}
|
|
||||||
deriving anyclass (Aeson.ToJSON, Aeson.FromJSON)
|
|
||||||
deriving stock (Show, Eq, GHC.Generic, Ord)
|
|
||||||
deriving anyclass (Hashable)
|
|
||||||
|
|
||||||
-- | Run a query on Builders.
|
|
||||||
runQuery :: ScriptQuery -> Builders -> Aeson.Value
|
|
||||||
runQuery s (Builders b) =
|
|
||||||
maybe Aeson.Null ($ s.paramsPayload) (Map.lookup s.name b)
|
|
||||||
|
|
||||||
throughJSON :: (Aeson.FromJSON p, Aeson.ToJSON s) => (p -> s) -> (Aeson.Value -> Aeson.Value)
|
|
||||||
throughJSON f = Aeson.toJSON . \case { Aeson.Error _ -> Nothing; Aeson.Success v -> Just (f v) } . Aeson.fromJSON
|
|
||||||
|
|
||||||
-- | Represents a list of named pure functions.
|
|
||||||
newtype Builders = Builders
|
|
||||||
{ getBuilders :: Map Text (Aeson.Value -> Aeson.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
instance Default Builders where
|
|
||||||
def = Builders Map.empty
|
|
||||||
|
|
||||||
-- | Insert a pure function into the Builders map.
|
|
||||||
insertBuilder :: (Aeson.FromJSON p, Aeson.ToJSON s) => Text -> (p -> s) -> Builders -> Builders
|
|
||||||
insertBuilder k = coerce . Map.insert k . throughJSON
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"governorInitialSpend": {
|
|
||||||
"txOutRefId": "7be688c61c209dd7a9f4948090db0b031b11a8850b0ee4695f786fea85fbfdee",
|
|
||||||
"txOutRefIdx": 0
|
|
||||||
},
|
|
||||||
"gtClassRef": [
|
|
||||||
"",
|
|
||||||
""
|
|
||||||
],
|
|
||||||
"maximumCosigners": 5
|
|
||||||
}
|
|
||||||
|
|
@ -232,14 +232,14 @@ benchmark agora-bench
|
||||||
|
|
||||||
executable agora-scripts
|
executable agora-scripts
|
||||||
import: lang, deps, exe-opts
|
import: lang, deps, exe-opts
|
||||||
main-is: Scripts.hs
|
main-is: Main.hs
|
||||||
hs-source-dirs: agora-scripts
|
hs-source-dirs: agora-scripts
|
||||||
other-modules:
|
other-modules:
|
||||||
API
|
|
||||||
Codec.Serialise.Orphans
|
Codec.Serialise.Orphans
|
||||||
Data.Cache.Cached
|
Data.Cache.Cached
|
||||||
Options
|
ScriptExport.API
|
||||||
Types
|
ScriptExport.Options
|
||||||
|
ScriptExport.Types
|
||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
, agora
|
, agora
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue