Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using a config file #75

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8ff25c6
Marshaling config-value to haskell data for PABConfig
ryukzak Mar 9, 2022
01643ab
Serialization ProtocalParameters to config-value.
ryukzak Mar 10, 2022
bd49adf
Serialize/deserialize PABConfig.
ryukzak Mar 11, 2022
753e639
Add non-default test for serialize/deserialize PABConfig. Fixes
ryukzak Mar 15, 2022
4cbf748
Restructured for future reuse
ryukzak Mar 15, 2022
72920ae
Refactoring
ryukzak Mar 15, 2022
2cd31c9
Fix and improve embedded config documentation.
ryukzak Mar 16, 2022
9ffd191
Add information about default values in auto generated docs.
ryukzak Mar 16, 2022
284c6de
Refactoring src/BotPlutusInterface/Config/Base.hs
ryukzak Mar 18, 2022
f25c719
Fix build error.
ryukzak Mar 21, 2022
8405dcb
Explicit imports. Refactoring. Docs.
ryukzak Mar 21, 2022
a8c1e6e
Explicit type application in type signs.
ryukzak Mar 21, 2022
01e3718
Refactoring
ryukzak Mar 22, 2022
09c90a5
Ban direct protocolParams config. Use pcProtocolParamsFile.
ryukzak Mar 22, 2022
ea1c04e
Apply hlint suggestions.
ryukzak Mar 23, 2022
5d0edbf
Make PubKeyHash more human-readable
ryukzak Mar 23, 2022
0eeba7d
Add new line to savePABConfig
ryukzak Mar 23, 2022
90031e2
Migrate examples on external config
ryukzak Mar 23, 2022
8f648a4
Fix format.
ryukzak Mar 23, 2022
8cdfc75
Update README
ryukzak Mar 24, 2022
1af3cc1
Update plutus
samuelWilliams99 Mar 22, 2022
5dc09c3
Restrict hedgehog version
samuelWilliams99 Mar 22, 2022
9ede5c8
Resolve build issues after update
szg251 Mar 23, 2022
2eaf333
Fix imports
samuelWilliams99 Mar 24, 2022
f75766f
Merge branch 'master' into sam/update-apps
samuelWilliams99 Mar 24, 2022
0378127
Merge remote-tracking branch 'origin/sam/update-apps' into aleksandr/…
ryukzak Mar 25, 2022
f7f0557
Add pcForceBudget to configuration.
ryukzak Mar 25, 2022
6808161
Fix format
ryukzak Mar 25, 2022
ba97efe
Update README
ryukzak Mar 25, 2022
8943d03
Fix cabal.project and hie.yaml (by gen-hie) for LSP
Apr 1, 2022
f740d22
Prepare PlutusConfig to extraction
Apr 5, 2022
901364e
Move PlutusConfig to submodule
Apr 6, 2022
5705204
Update github action
Apr 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions bot-plutus-interface.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ library
BotPlutusInterface
BotPlutusInterface.CardanoCLI
BotPlutusInterface.ChainIndex
BotPlutusInterface.Config
BotPlutusInterface.Config.Base
BotPlutusInterface.Config.Cardano.Api
BotPlutusInterface.Config.Cardano.Api.Shelley
BotPlutusInterface.Config.Ledger
BotPlutusInterface.Config.Types
BotPlutusInterface.Contract
BotPlutusInterface.Effects
BotPlutusInterface.Files
Expand All @@ -92,6 +98,8 @@ library
, cardano-api
, cardano-crypto
, cardano-ledger-alonzo
, config-schema
, config-value
, containers
, data-default
, data-default-class
Expand All @@ -117,17 +125,21 @@ library
, plutus-pab
, plutus-tx
, plutus-tx-plugin
, pretty
, process
, QuickCheck
, regex-compat
, row-types
, serialise
, servant
, servant-client
, servant-client-core
, servant-server
, servant-websockets
, split
, stm
, text ^>=1.2.4.0
, tostring
, transformers
, transformers-either
, uuid
Expand All @@ -144,6 +156,7 @@ test-suite bot-plutus-interface-test
ghc-options: -fplugin-opt PlutusTx.Plugin:defer-errors
other-modules:
Spec.BotPlutusInterface.Contract
Spec.BotPlutusInterface.Config
Spec.BotPlutusInterface.Balance
Spec.BotPlutusInterface.UtxoParser
Spec.BotPlutusInterface.Server
Expand All @@ -158,6 +171,8 @@ test-suite bot-plutus-interface-test
, bytestring ^>=0.10.12.0
, cardano-api
, cardano-crypto-class
, config-schema
, config-value
, containers
, data-default
, data-default-class
Expand Down
174 changes: 174 additions & 0 deletions src/BotPlutusInterface/Config.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}

{-# OPTIONS -fno-warn-orphans #-}

module BotPlutusInterface.Config (
docPABConfig,
loadPABConfig,
savePABConfig,
customRationalSpec,
) where

import BotPlutusInterface.Config.Base (customRationalSpec, filepathSpec, pathSpec, portSpec)
import BotPlutusInterface.Config.Cardano.Api ()
import BotPlutusInterface.Config.Cardano.Api.Shelley ()
import BotPlutusInterface.Config.Ledger ()
import BotPlutusInterface.Config.Types
import BotPlutusInterface.Types
import Config
import Config.Schema
import Data.Default
import Data.String
import Data.Text qualified as Text
import Prelude

instance ToValue CLILocation where
toValue Local =
Atom () "local"
toValue (Remote url) = Text () url

cliLocationSpec :: ValueSpec CLILocation
cliLocationSpec =
Local <$ atomSpec "local"
<!> Remote <$> withNamePrefixSpec "destination" anySpec

instance ToValue LogLevel where
toValue = Atom () . MkAtom . Text.toLower . Text.pack . show

logLevelSpec :: ValueSpec LogLevel
logLevelSpec =
Error <$ atomSpec "error"
<!> Warn <$ atomSpec "warn"
<!> Notice <$ atomSpec "notice"
<!> Info <$ atomSpec "info"
<!> Debug <$ atomSpec "debug"

{- ORMOLU_DISABLE -}
instance ToValue PABConfig where
toValue
( PABConfig
pcCliLocation
pcChainIndexUrl
pcNetwork
pcProtocolParams
pcSlotConfig
pcScriptFileDir
pcSigningKeyFileDir
pcTxFileDir
pcProtocolParamsFile
pcDryRun
pcLogLevel
pcOwnPubKeyHash
pcTipPollingInterval
pcPort
pcEnableTxEndpoint
) =
Sections
()
[ Section () "cliLocation" $ toValue pcCliLocation
, Section () "chainIndexUrl" $ toValue pcChainIndexUrl
, Section () "networkId" $ toValue pcNetwork
, Section () "protocolParams" $ toValue pcProtocolParams
, Section () "slotConfig" $ toValue pcSlotConfig
, Section () "scriptFileDir" $ toValue pcScriptFileDir
, Section () "signingKeyFileDir" $ toValue pcSigningKeyFileDir
, Section () "txFileDir" $ toValue pcTxFileDir
, Section () "protocolParamsFile" $ toValue pcProtocolParamsFile
, Section () "dryRun" $ toValue pcDryRun
, Section () "logLevel" $ toValue pcLogLevel
, Section () "ownPubKeyHash" $ toValue pcOwnPubKeyHash
, Section () "tipPollingInterval" $ toValue pcTipPollingInterval
, Section () "port" $ toValue pcPort
, Section () "enableTxEndpoint" $ toValue pcEnableTxEndpoint
]
{- ORMOLU_ENABLE -}

instance HasSpec PABConfig where
anySpec = pabConfigSpec

pabConfigSpec :: ValueSpec PABConfig
pabConfigSpec = sectionsSpec "PABConfig" $ do
pcCliLocation <-
sectionWithDefault'
(pcCliLocation def)
"cliLocation"
cliLocationSpec
"calling the cli through ssh when set to destination"

pcChainIndexUrl <-
sectionWithDefault (pcChainIndexUrl def) "chainIndexUrl" ""

pcNetwork <-
sectionWithDefault (pcNetwork def) "networkId" ""

pcProtocolParams <-
sectionWithDefault (pcProtocolParams def) "protocolParams" ""

pcSlotConfig <-
sectionWithDefault (pcSlotConfig def) "slotConfig" ""

pcScriptFileDir <-
sectionWithDefault'
(pcScriptFileDir def)
"scriptFileDir"
pathSpec
"Directory name of the script and data files"

pcSigningKeyFileDir <-
sectionWithDefault'
(pcSigningKeyFileDir def)
"signingKeyFileDir"
pathSpec
"Directory name of the signing key files"

pcTxFileDir <-
sectionWithDefault'
(pcTxFileDir def)
"txFileDir"
pathSpec
"Directory name of the transaction files"

pcProtocolParamsFile <-
sectionWithDefault'
(pcProtocolParamsFile def)
"protocolParamsFile"
filepathSpec
$ Text.concat
[ "Protocol params file location relative to the cardano-cli working directory (needed for the cli) in JSON format. "
, "BE AWARE: can overwrite the 'pcProtocolParams' section."
]

pcDryRun <-
sectionWithDefault'
(pcDryRun def)
"dryRun"
trueOrFalseSpec
"Dry run mode will build the tx, but skip the submit step"

pcLogLevel <-
sectionWithDefault' (pcLogLevel def) "logLevel" logLevelSpec ""

pcOwnPubKeyHash <-
sectionWithDefault (pcOwnPubKeyHash def) "ownPubKeyHash" ""

pcTipPollingInterval <-
sectionWithDefault' (pcTipPollingInterval def) "tipPollingInterval" naturalSpec ""

pcPort <-
sectionWithDefault' (pcPort def) "port" portSpec ""

pcEnableTxEndpoint <-
sectionWithDefault' (pcEnableTxEndpoint def) "enableTxEndpoint" trueOrFalseSpec ""

pure PABConfig {..}

docPABConfig :: String
docPABConfig = show $ generateDocs pabConfigSpec

loadPABConfig :: FilePath -> IO (Either String PABConfig)
loadPABConfig fn = deserialize <$> readFile fn

savePABConfig :: FilePath -> PABConfig -> IO ()
savePABConfig fn conf = writeFile fn $ serialize conf
107 changes: 107 additions & 0 deletions src/BotPlutusInterface/Config/Base.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
{-# OPTIONS -fno-warn-orphans #-}

module BotPlutusInterface.Config.Base (
maybeSpec,
customRationalSpec,
portSpec,
pathSpec,
filepathSpec,
toValueTextViaJSON,
textSpecViaJSON,
) where

import BotPlutusInterface.Config.Types
import BotPlutusInterface.Types ()
import Config
import Config.Schema
import Data.Aeson (FromJSON, ToJSON, eitherDecode, encode)
import Data.Ratio ((%))
import Data.String
import Data.String.ToString
import Data.Text (Text)
import Data.Text qualified as Text
import Network.Wai.Handler.Warp (Port)
import Numeric.Natural (Natural)
import Servant.Client.Core (BaseUrl (..), parseBaseUrl, showBaseUrl)
import Text.Regex
import Prelude

instance ToValue Bool where
toValue = Atom () . MkAtom . Text.toLower . Text.pack . show

instance ToValue Natural where
toValue x = Number () $ integerToNumber $ toInteger x

instance ToValue Integer where
toValue x = Number () $ integerToNumber x

instance ToValue Text where
toValue = Text ()

instance (ToValue a) => ToValue (Maybe a) where
toValue = maybe (Atom () "nothing") toValue

maybeSpec :: ValueSpec a -> ValueSpec (Maybe a)
maybeSpec spec =
Nothing <$ atomSpec "nothing"
<!> Just <$> spec

instance ToValue Rational where
toValue x = Text () $ Text.pack $ show x

customRationalSpec :: ValueSpec Rational
customRationalSpec =
customSpec
"Ratio number (\"1 % 2\") in"
stringSpec
( \x -> case matchRegex ratioRE x of
Just [n, d] ->
let n' = read n
d' = read d
in if d' == 0
then Left "denominator should not be zero"
else Right $ n' % d'
_ -> Left $ Text.pack "Ratio format: '1 % 2'"
)
where
ratioRE = mkRegex "^ *([0-9]+) *% *([0-9]+) *$"

pathSpec :: ValueSpec Text
pathSpec = withNamePrefixSpec "path" anySpec

filepathSpec :: ValueSpec Text
filepathSpec = withNamePrefixSpec "filepath" anySpec

toValueTextViaJSON :: (ToJSON a) => a -> Value ()
toValueTextViaJSON = Text () . Text.pack . filter (/= '"') . toString . encode

textSpecViaJSON :: (FromJSON a) => Text -> ValueSpec a
textSpecViaJSON name =
customSpec
name
textSpec
( \s -> case eitherDecode $ fromString $ wrap $ toString s of
Left err -> Left $ "parse error: " <> fromString err
Right res -> Right res
)
where
wrap s = "\"" <> s <> "\""

instance ToValue BaseUrl where
toValue = Text () . Text.pack . showBaseUrl

instance HasSpec BaseUrl where
anySpec = baseUrlSpec

baseUrlSpec :: ValueSpec BaseUrl
baseUrlSpec =
customSpec
"url"
anySpec
(first Text.showText . parseBaseUrl . Text.unpack)

instance ToValue Port where
toValue = Number () . integerToNumber . toInteger

portSpec :: ValueSpec Port
portSpec = fromEnum <$> customSpec "port" naturalSpec Right
Loading