diff --git a/agora-scripts/API.hs b/agora-scripts/API.hs deleted file mode 100644 index efccc4e..0000000 --- a/agora-scripts/API.hs +++ /dev/null @@ -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 diff --git a/agora-scripts/Codec/Serialise/Orphans.hs b/agora-scripts/Codec/Serialise/Orphans.hs index 62d69bf..f310abd 100644 --- a/agora-scripts/Codec/Serialise/Orphans.hs +++ b/agora-scripts/Codec/Serialise/Orphans.hs @@ -9,12 +9,10 @@ Orphan instances for Serialising and Hashing Cardano types. -} module Codec.Serialise.Orphans () where -import Codec.Serialise (Serialise, serialise) -import Data.Hashable (Hashable (hashWithSalt)) +import Codec.Serialise (Serialise) import Data.Tagged (Tagged (Tagged)) import PlutusLedgerApi.V1 (TxId, TxOutRef) import PlutusLedgerApi.V1.Value (AssetClass, CurrencySymbol, TokenName) -import Types (ScriptParams) deriving anyclass instance Serialise TxOutRef @@ -34,8 +32,3 @@ deriving anyclass instance deriving newtype instance Serialise a => Serialise (Tagged s a) - -deriving anyclass instance Serialise ScriptParams - -instance Hashable ScriptParams where - hashWithSalt s scriptParams = hashWithSalt s (serialise scriptParams) diff --git a/agora-scripts/Main.hs b/agora-scripts/Main.hs new file mode 100644 index 0000000..3bb85a1 --- /dev/null +++ b/agora-scripts/Main.hs @@ -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 + ) diff --git a/agora-scripts/ScriptExport/API.hs b/agora-scripts/ScriptExport/API.hs new file mode 100644 index 0000000..e074dab --- /dev/null +++ b/agora-scripts/ScriptExport/API.hs @@ -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 diff --git a/agora-scripts/Options.hs b/agora-scripts/ScriptExport/Options.hs similarity index 89% rename from agora-scripts/Options.hs rename to agora-scripts/ScriptExport/Options.hs index b0fa855..b37da56 100644 --- a/agora-scripts/Options.hs +++ b/agora-scripts/ScriptExport/Options.hs @@ -1,11 +1,11 @@ {- | -Module : Options +Module : ScriptExport.Options Maintainer : emi@haskell.fyi Description: 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 Options.Applicative ((<**>)) diff --git a/agora-scripts/ScriptExport/Types.hs b/agora-scripts/ScriptExport/Types.hs new file mode 100644 index 0000000..b7dfcac --- /dev/null +++ b/agora-scripts/ScriptExport/Types.hs @@ -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 diff --git a/agora-scripts/Scripts.hs b/agora-scripts/Scripts.hs deleted file mode 100644 index a665c96..0000000 --- a/agora-scripts/Scripts.hs +++ /dev/null @@ -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 diff --git a/agora-scripts/Types.hs b/agora-scripts/Types.hs deleted file mode 100644 index 7a36404..0000000 --- a/agora-scripts/Types.hs +++ /dev/null @@ -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 diff --git a/agora-scripts/agora-params.json b/agora-scripts/agora-params.json deleted file mode 100644 index abb0f3d..0000000 --- a/agora-scripts/agora-params.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "governorInitialSpend": { - "txOutRefId": "7be688c61c209dd7a9f4948090db0b031b11a8850b0ee4695f786fea85fbfdee", - "txOutRefIdx": 0 - }, - "gtClassRef": [ - "", - "" - ], - "maximumCosigners": 5 -} diff --git a/agora.cabal b/agora.cabal index 83d3189..b84abed 100644 --- a/agora.cabal +++ b/agora.cabal @@ -232,14 +232,14 @@ benchmark agora-bench executable agora-scripts import: lang, deps, exe-opts - main-is: Scripts.hs + main-is: Main.hs hs-source-dirs: agora-scripts other-modules: - API Codec.Serialise.Orphans Data.Cache.Cached - Options - Types + ScriptExport.API + ScriptExport.Options + ScriptExport.Types build-depends: , agora