add granular script querying support
This commit is contained in:
parent
e862de7e59
commit
5f2d191ae7
5 changed files with 89 additions and 7 deletions
|
|
@ -25,7 +25,9 @@ import Agora.Stake (Stake (..))
|
||||||
import Agora.Stake.Scripts (stakePolicy, stakeValidator)
|
import Agora.Stake.Scripts (stakePolicy, stakeValidator)
|
||||||
import Agora.Treasury (treasuryValidator)
|
import Agora.Treasury (treasuryValidator)
|
||||||
import Codec.Serialise.Orphans ()
|
import Codec.Serialise.Orphans ()
|
||||||
|
import Data.Aeson qualified as Aeson
|
||||||
import Data.Cache.Cached (cachedFor)
|
import Data.Cache.Cached (cachedFor)
|
||||||
|
import Data.Default.Class (Default (def))
|
||||||
import Data.Function ((&))
|
import Data.Function ((&))
|
||||||
import Data.Proxy (Proxy (Proxy))
|
import Data.Proxy (Proxy (Proxy))
|
||||||
import Development.GitRev (gitBranch, gitHash)
|
import Development.GitRev (gitBranch, gitHash)
|
||||||
|
|
@ -39,14 +41,16 @@ import PlutusLedgerApi.V1.Value (AssetClass, CurrencySymbol)
|
||||||
import PlutusLedgerApi.V1.Value qualified as Value
|
import PlutusLedgerApi.V1.Value qualified as Value
|
||||||
import Prettyprinter (defaultLayoutOptions, hsep, layoutPretty, viaShow, (<+>))
|
import Prettyprinter (defaultLayoutOptions, hsep, layoutPretty, viaShow, (<+>))
|
||||||
import Prettyprinter.Render.String (renderString)
|
import Prettyprinter.Render.String (renderString)
|
||||||
import Servant.API (JSON, Post, ReqBody, type (:>))
|
import Servant.API (JSON, Post, ReqBody, (:<|>) (..), type (:>))
|
||||||
import Servant.Server qualified as Servant
|
import Servant.Server qualified as Servant
|
||||||
import System.Clock (TimeSpec (TimeSpec))
|
import System.Clock (TimeSpec (TimeSpec))
|
||||||
import Text.Printf (printf)
|
import Text.Printf (printf)
|
||||||
import Types (AgoraScripts (..), ScriptParams (..))
|
import Types (AgoraScripts (..), Builders, ScriptParams (..), ScriptQuery, insertBuilder, runQuery)
|
||||||
|
|
||||||
-- | Servant API type for script generation.
|
-- | Servant API type for script generation.
|
||||||
type API = "generate-scripts" :> ReqBody '[JSON] ScriptParams :> Post '[JSON] AgoraScripts
|
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.
|
-- | Run a Warp server that exposes a script generation endpoint.
|
||||||
runServer :: Options -> IO ()
|
runServer :: Options -> IO ()
|
||||||
|
|
@ -74,12 +78,27 @@ runServer options = do
|
||||||
|
|
||||||
-- Scripts stay cached for five minutes
|
-- Scripts stay cached for five minutes
|
||||||
agoraScripts' <- cachedFor (Just $ TimeSpec 300 0) agoraScripts
|
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)
|
printf "[info] Running 'agora-scripts' on :%d\n" (Warp.getPort settings)
|
||||||
Servant.serve (Proxy @API) agoraScripts'
|
Servant.serve
|
||||||
|
(Proxy @API)
|
||||||
|
(agoraScripts' :<|> query)
|
||||||
& corsMiddleware
|
& corsMiddleware
|
||||||
& Warp.runSettings settings
|
& 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.
|
-- | Create scripts from params.
|
||||||
agoraScripts :: ScriptParams -> AgoraScripts
|
agoraScripts :: ScriptParams -> AgoraScripts
|
||||||
agoraScripts params =
|
agoraScripts params =
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,26 @@ Description: Param and script types for generation.
|
||||||
|
|
||||||
Param and script types for generation.
|
Param and script types for generation.
|
||||||
-}
|
-}
|
||||||
module Types (ScriptParams (..), AgoraScripts (..)) where
|
module Types (
|
||||||
|
ScriptParams (..),
|
||||||
|
AgoraScripts (..),
|
||||||
|
ScriptQuery (..),
|
||||||
|
Builders (..),
|
||||||
|
throughJSON,
|
||||||
|
runQuery,
|
||||||
|
insertBuilder,
|
||||||
|
) where
|
||||||
|
|
||||||
import Agora.SafeMoney (GTTag)
|
import Agora.SafeMoney (GTTag)
|
||||||
import Agora.ScriptInfo (PolicyInfo, ValidatorInfo)
|
import Agora.ScriptInfo (PolicyInfo, ValidatorInfo)
|
||||||
import Data.Aeson qualified as Aeson
|
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.Tagged (Tagged)
|
||||||
|
import Data.Text (Text)
|
||||||
import GHC.Generics qualified as GHC
|
import GHC.Generics qualified as GHC
|
||||||
import PlutusLedgerApi.V1 (TxOutRef)
|
import PlutusLedgerApi.V1 (TxOutRef)
|
||||||
import PlutusLedgerApi.V1.Value (AssetClass)
|
import PlutusLedgerApi.V1.Value (AssetClass)
|
||||||
|
|
@ -40,3 +54,31 @@ data AgoraScripts = AgoraScripts
|
||||||
}
|
}
|
||||||
deriving anyclass (Aeson.ToJSON, Aeson.FromJSON)
|
deriving anyclass (Aeson.ToJSON, Aeson.FromJSON)
|
||||||
deriving stock (Show, Eq, GHC.Generic)
|
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
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ common lang
|
||||||
BinaryLiterals
|
BinaryLiterals
|
||||||
ConstrainedClassMethods
|
ConstrainedClassMethods
|
||||||
ConstraintKinds
|
ConstraintKinds
|
||||||
|
DuplicateRecordFields
|
||||||
DataKinds
|
DataKinds
|
||||||
DeriveAnyClass
|
DeriveAnyClass
|
||||||
DeriveDataTypeable
|
DeriveDataTypeable
|
||||||
|
|
@ -255,6 +256,7 @@ executable agora-scripts
|
||||||
, wai
|
, wai
|
||||||
, wai-cors
|
, wai-cors
|
||||||
, warp
|
, warp
|
||||||
|
, containers
|
||||||
|
|
||||||
executable agora-purescript-bridge
|
executable agora-purescript-bridge
|
||||||
import: lang, deps, exe-opts
|
import: lang, deps, exe-opts
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,15 @@ deriving via
|
||||||
instance
|
instance
|
||||||
(Aeson.FromJSON Plutus.ValidatorHash)
|
(Aeson.FromJSON Plutus.ValidatorHash)
|
||||||
|
|
||||||
|
deriving via
|
||||||
|
(AsBase16Bytes Plutus.BuiltinByteString)
|
||||||
|
instance
|
||||||
|
(Aeson.ToJSON Plutus.BuiltinByteString)
|
||||||
|
deriving via
|
||||||
|
(AsBase16Bytes Plutus.BuiltinByteString)
|
||||||
|
instance
|
||||||
|
(Aeson.FromJSON Plutus.BuiltinByteString)
|
||||||
|
|
||||||
deriving via
|
deriving via
|
||||||
(AsBase16Codec Plutus.Validator)
|
(AsBase16Codec Plutus.Validator)
|
||||||
instance
|
instance
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ module Agora.ScriptInfo (
|
||||||
-- * Types
|
-- * Types
|
||||||
PolicyInfo (..),
|
PolicyInfo (..),
|
||||||
ValidatorInfo (..),
|
ValidatorInfo (..),
|
||||||
|
ScriptInfo (..),
|
||||||
|
|
||||||
-- * Introduction functions
|
-- * Introduction functions
|
||||||
mkValidatorInfo,
|
mkValidatorInfo,
|
||||||
|
|
@ -19,8 +20,17 @@ import Agora.Aeson.Orphans ()
|
||||||
import Data.Aeson qualified as Aeson
|
import Data.Aeson qualified as Aeson
|
||||||
import GHC.Generics qualified as GHC
|
import GHC.Generics qualified as GHC
|
||||||
import Plutarch.Api.V1 (PMintingPolicy, PValidator, mintingPolicySymbol, mkMintingPolicy, mkValidator, validatorHash)
|
import Plutarch.Api.V1 (PMintingPolicy, PValidator, mintingPolicySymbol, mkMintingPolicy, mkValidator, validatorHash)
|
||||||
import PlutusLedgerApi.V1 (MintingPolicy, Validator, ValidatorHash)
|
import PlutusLedgerApi.V1 (BuiltinByteString, CurrencySymbol (unCurrencySymbol), MintingPolicy, Script, Validator, ValidatorHash, unMintingPolicyScript)
|
||||||
import PlutusLedgerApi.V1.Value (CurrencySymbol)
|
|
||||||
|
-- | Bundle containing a 'Script' and its hash.
|
||||||
|
data ScriptInfo = ScriptInfo
|
||||||
|
{ script :: Script
|
||||||
|
-- ^ The validator script.
|
||||||
|
, hash :: BuiltinByteString
|
||||||
|
-- ^ Hash of the script.
|
||||||
|
}
|
||||||
|
deriving stock (Show, Eq, GHC.Generic)
|
||||||
|
deriving anyclass (Aeson.ToJSON, Aeson.FromJSON)
|
||||||
|
|
||||||
{- | Bundle containing a 'Validator' and its hash.
|
{- | Bundle containing a 'Validator' and its hash.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue