Server seems to have built ok:
[nix-shell:~/plutus/plutus-starter]$ cabal build plutus-starter-pab
Resolving dependencies...
Up to date
I am using Plutus-Starter project on Macbook Monterey M1 but have not been able to generate the wallet Ids or confirm that the server fully started. It seems to just say "[INFO] Starting PAB backend server on port 9080" full log is below. Is there a verbose mode for starting the server?
[nix-shell:~/plutus/plutus-starter]$ cabal exec -- plutus-starter-pab
[INFO] Slot 0: TxnValidate 08111487e032e647e23e6e6866665ab726a4c92532e9589f9e670f2585e35807
[INFO] Starting plutus-starter PAB webserver on port 9080. Press enter to exit.
[INFO] W[2]: Balancing an unbalanced transaction:
Tx:
Tx 318797441458154cf284463902d8e152cc240ab65a58fff5287b0a1f5d5de3a1:
{inputs:
collateral inputs:
outputs:
- Value (Map [(,Map [("",10000000000)])]) addressed to
PubKeyCredential: bb22a3608c50bdb141d2f1255836a7f4fc829a47d801c985746cfca6 (no staking credential)
mint: Value (Map [])
fee: Value (Map [])
mps:
signatures:
validity range: Interval {ivFrom = LowerBound NegInf True, ivTo = UpperBound PosInf True}
data:}
Requires signatures:
Utxo index:
Validity range:
(-∞ , +∞)
[INFO] W[2]: Finished balancing:
Tx e5581a9ec85d0525e8aee67e8ec2e453b6e098121aa29fab8698ff091ebd3bd6:
{inputs:
- 08111487e032e647e23e6e6866665ab726a4c92532e9589f9e670f2585e35807!20
- 08111487e032e647e23e6e6866665ab726a4c92532e9589f9e670f2585e35807!21
collateral inputs:
- 08111487e032e647e23e6e6866665ab726a4c92532e9589f9e670f2585e35807!20
outputs:
- Value (Map [(,Map [("",9999999489)])]) addressed to
PubKeyCredential: 80a4f45b56b88d1139da23bc4c3c75ec6d32943c087f250b86193ca7 (no staking credential)
- Value (Map [(,Map [("",10000000000)])]) addressed to
PubKeyCredential: bb22a3608c50bdb141d2f1255836a7f4fc829a47d801c985746cfca6 (no staking credential)
mint: Value (Map [])
fee: Value (Map [(,Map [("",511)])])
mps:
signatures:
validity range: Interval {ivFrom = LowerBound NegInf True, ivTo = UpperBound PosInf True}
data:}
[INFO] W[2]: Signing tx: e5581a9ec85d0525e8aee67e8ec2e453b6e098121aa29fab8698ff091ebd3bd6
[INFO] W[2]: Submitting tx: e5581a9ec85d0525e8aee67e8ec2e453b6e098121aa29fab8698ff091ebd3bd6
[INFO] Slot 1: TxnValidate e5581a9ec85d0525e8aee67e8ec2e453b6e098121aa29fab8698ff091ebd3bd6
[INFO] Starting PAB backend server on port 9080
I don't see confirmation that it fully started but there is a response to service definition request:
% curl -s http://localhost:9080/api/contract/definitions | jq
[
{
"csrSchemas": [
{
"argument": {
"contents": [
[
"guessWord",
{
"tag": "FormSchemaString"
}
]
],
"tag": "FormSchemaObject"
},
"endpointDescription": {
"getEndpointDescription": "guess"
}
},
{
"argument": {
"contents": [
[
"secretWord",
{
"tag": "FormSchemaString"
}
],
[
"amount",
{
"tag": "FormSchemaValue"
}
]
],
"tag": "FormSchemaObject"
},
"endpointDescription": {
"getEndpointDescription": "lock"
}
}
],
"csrDefinition": "GameContract"
}
]
This does not seem to include enough endpoint information.
And the Wallet Creation request returns empty
deano@Ds-MacBook-Pro ~ % curl -s -d '' http://localhost:9080/wallet/create
deano@Ds-MacBook-Pro ~ %
Update: Digging into the source I see some instructions in a readme file related to starting the PAB backend server for a local cluster but I am not sure this is related.
cat ./dist-newstyle/src/plutus-ap_-cbcc5c6ab544aad6/plutus-pab-executables/README.md
#### Example
1. Build necessary components:
cabal build plutus-pab-local-cluster
2. Get config data:
Clone <https://github.com/input-output-hk/cardano-wallet/> to $DIR and set the
`SHELLEY_TEST_DATA` environment variable:
export SHELLEY_TEST_DATA=$DIR/lib/shelley/test/data/cardano-node-shelley
3. Run the local cluster:
cabal exec plutus-pab-local-cluster
4. Wait until the message `Starting PAB backend server on port 9080` appears.
5. Run the integration test:
curl -H "Content-Type: application/json" -v \
-X POST \
-d '{"caID":{"tag":"IntegrationTest"},"caWallet":{"getWalletId":"2d4cc31a4b3116ab86bfe529d30d9c362acd0b44"}}' \
localhost:9080/api/contract/activate
A couple of log messages appear, the last one should say something like "Tx
confirmed. Integration test complete."
PAB Server starting message seems to be in PABLogMsg
I don't see there there is any message available within PABLogMsg to confirm a successful start. I think there are no further messages about this. However there is some reason the PAB Server cannot create the walletId. Do I need to be running anything else for this to work?
[nix-shell:~/plutus/plutus-starter]$ cat ./dist-newstyle/src/plutus-ap_-cbcc5c6ab544aad6/plutus-pab/src/Plutus/PAB/Monitoring/PABLogMsg.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
-- | PAB Log messages and instances
module Plutus.PAB.Monitoring.PABLogMsg(
PABLogMsg(..),
ChainIndexServerMsg,
WalletMsg,
PABServerLogMsg,
AppMsg(..),
CoreMsg(..),
PABMultiAgentMsg(..),
RequestSize(..),
WalletClientMsg(..)
) where
import Cardano.Api qualified as C
import Cardano.BM.Data.Tracer (ToObject (toObject), TracingVerbosity (MaximalVerbosity))
import Cardano.BM.Data.Tracer.Extras (StructuredLog, Tagged (Tagged), mkObjectStr)
import Cardano.ChainIndex.Types (ChainIndexServerMsg)
import Cardano.Node.Types (PABServerConfig, PABServerLogMsg)
import Cardano.Wallet.Mock.Types (WalletMsg)
import Control.Monad.Freer.Extras.Beam (BeamLog)
import Data.Aeson (FromJSON, ToJSON, Value)
import Data.Aeson.Text (encodeToLazyText)
import Data.Text (Text)
import Data.Text qualified as T
import GHC.Generics (Generic)
import Plutus.Contract.Effects (PABReq, PABResp)
import Plutus.Contract.Resumable (Response)
import Plutus.Contract.State (ContractResponse)
import Plutus.PAB.Core.ContractInstance (ContractInstanceMsg)
import Plutus.PAB.Effects.Contract (PABContract (..))
import Plutus.PAB.Events.Contract (ContractInstanceId)
import Plutus.PAB.Instances ()
import Prettyprinter (Pretty (pretty), colon, line, viaShow, (<+>))
import Wallet.Emulator.LogMessages (TxBalanceMsg)
import Wallet.Emulator.MultiAgent (EmulatorEvent)
import Wallet.Emulator.Wallet (Wallet)
data WalletClientMsg =
WalletClientError String
| BalanceTxError String
deriving stock (Eq, Show, Generic)
deriving anyclass (ToJSON, FromJSON)
instance Pretty WalletClientMsg where
pretty = viaShow
instance ToObject WalletClientMsg where
toObject _ m = mkObjectStr (T.pack $ show m) ()
data AppMsg t =
ActiveContractsMsg
| ContractHistoryMsg
| PABMsg (PABLogMsg t)
| AvailableContract Text
| ContractInstances (ContractDef t) [ContractInstanceId]
| ContractHistoryItem ContractInstanceId (Response PABResp)
deriving stock (Generic)
deriving stock instance (Show (ContractDef t)) => Show (AppMsg t)
deriving anyclass instance (ToJSON (ContractDef t)) => ToJSON (AppMsg t)
deriving anyclass instance (FromJSON (ContractDef t)) => FromJSON (AppMsg t)
instance (Pretty (ContractDef t)) => Pretty (AppMsg t) where
pretty = \case
ActiveContractsMsg -> "Active contracts"
ContractHistoryMsg -> "Contract history"
PABMsg m -> pretty m
AvailableContract t -> pretty t
ContractInstances t s -> pretty t <+> pretty s
ContractHistoryItem instanceId s -> pretty instanceId <> colon <+> pretty (fmap encodeToLazyText s)
data PABLogMsg t =
SCoreMsg (CoreMsg t)
| SChainIndexServerMsg ChainIndexServerMsg
| SWalletMsg WalletMsg
| SMockserverLogMsg PABServerLogMsg
| SMultiAgent (PABMultiAgentMsg t)
deriving stock (Generic)
deriving stock instance (Show (ContractDef t)) => Show (PABLogMsg t)
deriving anyclass instance (ToJSON (ContractDef t)) => ToJSON (PABLogMsg t)
deriving anyclass instance (FromJSON (ContractDef t)) => FromJSON (PABLogMsg t)
instance Pretty (ContractDef t) => Pretty (PABLogMsg t) where
pretty = \case
SCoreMsg m -> pretty m
SChainIndexServerMsg m -> pretty m
SWalletMsg m -> pretty m
SMockserverLogMsg m -> pretty m
SMultiAgent m -> pretty m
{- ToObject instances
'ToObject.toObject' is very similar to 'ToJSON.toJSON' except that
* 'toObject' has an additional paramter for verbosity
* 'toObject' must always produce a JSON object (key-value map)
In the definitions below, every object produced by 'toObject' has a field
'string' with a friendly description of the message, similar to its
'Pretty' instance. Additional fields depend on the type of message.
-}
instance (ToJSON (ContractDef t), StructuredLog (ContractDef t)) => ToObject (AppMsg t) where
toObject v = \case
ActiveContractsMsg ->
mkObjectStr "Listing active contract instances" ()
ContractHistoryMsg ->
mkObjectStr "Showing contract history" ()
PABMsg m -> toObject v m
AvailableContract t ->
mkObjectStr "Available contract" t
ContractInstances exe ids ->
mkObjectStr
"Active instances for contract"
(exe, Tagged @"instances" ids)
ContractHistoryItem i state ->
mkObjectStr "Contract history item" $
case v of
MaximalVerbosity -> Left (i, state)
_ -> Right i
instance (StructuredLog (ContractDef t), ToJSON (ContractDef t)) => ToObject (PABLogMsg t) where
toObject v = \case
SCoreMsg m -> toObject v m
SChainIndexServerMsg m -> toObject v m
SWalletMsg m -> toObject v m
SMockserverLogMsg m -> toObject v m
SMultiAgent m -> toObject v m
-- | FIXME: Redundant?
data PABMultiAgentMsg t =
EmulatorMsg EmulatorEvent
| ContractInstanceLog (ContractInstanceMsg t)
| UserLog T.Text
| BeamLogItem BeamLog
| PABStateRestored Int
| RestoringPABState
| StartingPABBackendServer Int
| WalletBalancingMsg Wallet TxBalanceMsg
| WalletClient WalletClientMsg
deriving stock Generic
instance (StructuredLog (ContractDef t), ToJSON (ContractDef t)) => ToObject (PABMultiAgentMsg t) where
toObject v = \case
EmulatorMsg e -> mkObjectStr "emulator message" (Tagged @"payload" e)
ContractInstanceLog m -> toObject v m
UserLog t -> toObject v t
BeamLogItem b -> toObject v b
RestoringPABState -> mkObjectStr "Restoring PAB state ..." ()
PABStateRestored n -> mkObjectStr ( "PAB state restored with "
<> T.pack (show n)
<> " contract instance(s)."
) ()
StartingPABBackendServer i -> mkObjectStr "starting backend server" (Tagged @"port" i)
WalletBalancingMsg w m -> mkObjectStr "balancing" (Tagged @"wallet" w, Tagged @"message" m)
WalletClient m -> toObject v m
deriving stock instance (Show (ContractDef t)) => Show (PABMultiAgentMsg t)
deriving anyclass instance (ToJSON (ContractDef t)) => ToJSON (PABMultiAgentMsg t)
deriving anyclass instance (FromJSON (ContractDef t)) => FromJSON (PABMultiAgentMsg t)
instance Pretty (ContractDef t) => Pretty (PABMultiAgentMsg t) where
pretty = \case
EmulatorMsg m -> pretty m
ContractInstanceLog m -> pretty m
UserLog m -> pretty m
BeamLogItem b -> pretty b
RestoringPABState -> "Restoring PAB state ..."
PABStateRestored 0 -> "No contract instance were restored in the PAB state."
PABStateRestored 1 -> "PAB state restored with 1 contract instance."
PABStateRestored n -> "PAB state restored with"
<+> pretty n
<+> "contract instances."
StartingPABBackendServer port ->
"Starting PAB backend server on port" <+> pretty port
WalletBalancingMsg w m -> pretty w <> colon <+> pretty m
WalletClient m -> pretty m
data CoreMsg t =
FindingContract ContractInstanceId
| FoundContract (Maybe (ContractResponse Value Value PABResp PABReq))
| ConnectingToAlonzoNode PABServerConfig C.SlotNo
deriving stock Generic
deriving stock instance (Show (ContractDef t)) => Show (CoreMsg t)
deriving anyclass instance (ToJSON (ContractDef t)) => ToJSON (CoreMsg t)
deriving anyclass instance (FromJSON (ContractDef t)) => FromJSON (CoreMsg t)
instance Pretty (ContractDef t) => Pretty (CoreMsg t) where
pretty = \case
FindingContract i -> "Finding contract" <+> pretty i
FoundContract c -> "Found contract" <+> viaShow c
ConnectingToAlonzoNode config slotNo ->
"Connecting to Alonzo node with config:"
<> line
<> pretty config
<> line
<> "The tip of the local node:"
<+> viaShow slotNo
instance (StructuredLog (ContractDef t), ToJSON (ContractDef t)) => ToObject (CoreMsg t) where
toObject v = \case
FindingContract instanceID ->
mkObjectStr "finding contract instance" instanceID
FoundContract state ->
mkObjectStr "found contract" $
case v of
MaximalVerbosity -> Left (Tagged @"contract" state)
_ -> Right ()
ConnectingToAlonzoNode _ _ -> mkObjectStr "Connecting to Alonzo node" ()
newtype RequestSize = RequestSize Int
deriving stock (Show)
deriving newtype (ToJSON, FromJSON)
instance Pretty RequestSize where
pretty (RequestSize i) = pretty i <+> "bytes"