@@ -13,9 +13,10 @@ import BotPlutusInterface.Effects (
1313 queryChainIndex ,
1414 threadDelay ,
1515 )
16+ import BotPlutusInterface.Files (DummyPrivKey (FromSKey , FromVKey ))
1617import BotPlutusInterface.Files qualified as Files
1718import BotPlutusInterface.PreBalance qualified as PreBalance
18- import BotPlutusInterface.Types (ContractEnvironment (.. ), LogLevel (Debug ), Tip (slot ))
19+ import BotPlutusInterface.Types (ContractEnvironment (.. ), LogLevel (Debug , Warn ), Tip (slot ))
1920import Control.Lens ((^.) )
2021import Control.Monad (void )
2122import Control.Monad.Freer (Eff , Member , interpret , reinterpret , runM , subsume , type (~> ))
@@ -26,11 +27,14 @@ import Control.Monad.Freer.Writer (Writer (Tell))
2627import Control.Monad.Trans.Class (lift )
2728import Control.Monad.Trans.Either (eitherT , firstEitherT , newEitherT , secondEitherT )
2829import Data.Aeson (ToJSON , Value )
30+ import Data.Aeson.Extras (encodeByteString )
2931import Data.Kind (Type )
3032import Data.Map qualified as Map
3133import Data.Row (Row )
34+ import Data.Text (Text )
3235import Data.Text qualified as Text
3336import Ledger (POSIXTime )
37+ import Ledger qualified
3438import Ledger.Address (PaymentPubKeyHash (PaymentPubKeyHash ))
3539import Ledger.Constraints.OffChain (UnbalancedTx (.. ))
3640import Ledger.Slot (Slot (Slot ))
@@ -47,6 +51,7 @@ import Plutus.Contract.Effects (
4751 )
4852import Plutus.Contract.Resumable (Resumable (.. ))
4953import Plutus.Contract.Types (Contract (.. ), ContractEffs )
54+ import PlutusTx.Builtins (fromBuiltin )
5055import Wallet.Emulator.Error (WalletAPIError (.. ))
5156import Prelude
5257
@@ -182,23 +187,37 @@ writeBalancedTx ::
182187 Eff effs WriteBalancedTxResponse
183188writeBalancedTx _ (Left _) = error " Cannot handle cardano api tx"
184189writeBalancedTx contractEnv (Right tx) = do
185- createDirectoryIfMissing @ w False (Text. unpack contractEnv. cePABConfig. pcScriptFileDir)
190+ let pabConf = contractEnv. cePABConfig
191+ createDirectoryIfMissing @ w False (Text. unpack pabConf. pcScriptFileDir)
186192
187193 eitherT (pure . WriteBalancedTxFailed . OtherError ) (pure . WriteBalancedTxSuccess . Right ) $ do
188- void $ firstEitherT (Text. pack . show ) $ newEitherT $ Files. writeAll @ w contractEnv . cePABConfig tx
189- privKeys <- newEitherT $ Files. readPrivateKeys @ w contractEnv . cePABConfig
194+ void $ firstEitherT (Text. pack . show ) $ newEitherT $ Files. writeAll @ w pabConf tx
195+ privKeys <- newEitherT $ Files. readPrivateKeys @ w pabConf
190196
191- let ownPkh = contractEnv . cePABConfig . pcOwnPubKeyHash
197+ let ownPkh = pabConf . pcOwnPubKeyHash
192198 let requiredSigners = Map. keys $ tx ^. Tx. signatures
199+ let skeys = Map. filter (\ case FromSKey _ -> True ; FromVKey _ -> False ) privKeys
200+ let signable = all ((`Map.member` skeys) . Ledger. pubKeyHash) requiredSigners
193201
194- lift $ CardanoCLI. uploadFiles @ w contractEnv . cePABConfig
202+ lift $ CardanoCLI. uploadFiles @ w pabConf
195203
196- newEitherT $ CardanoCLI. buildTx @ w contractEnv. cePABConfig privKeys ownPkh CardanoCLI. BuildAuto tx
197- newEitherT $ CardanoCLI. signTx @ w contractEnv. cePABConfig privKeys tx requiredSigners
204+ newEitherT $ CardanoCLI. buildTx @ w pabConf privKeys ownPkh CardanoCLI. BuildAuto tx
198205
199- if contractEnv. cePABConfig. pcDryRun
200- then pure tx
201- else secondEitherT (const tx) $ newEitherT $ CardanoCLI. submitTx @ w contractEnv. cePABConfig tx
206+ if signable
207+ then newEitherT $ CardanoCLI. signTx @ w pabConf tx requiredSigners
208+ else
209+ lift . printLog @ w Warn . Text. unpack . Text. unlines $
210+ [ " Not all required signatures have signing key files. Please sign and submit the tx manually:"
211+ , " Tx file: " <> Files. txFilePath pabConf " raw" tx
212+ , " Signatories (pkh): " <> Text. unwords (map pkhToText requiredSigners)
213+ ]
214+
215+ if not pabConf. pcDryRun && signable
216+ then secondEitherT (const tx) $ newEitherT $ CardanoCLI. submitTx @ w pabConf tx
217+ else pure tx
218+
219+ pkhToText :: Ledger. PubKey -> Text
220+ pkhToText = encodeByteString . fromBuiltin . Ledger. getPubKeyHash . Ledger. pubKeyHash
202221
203222{- | Wait at least until the given slot. The slot number only changes when a new block is appended
204223 to the chain so it waits for at least one block
0 commit comments