Skip to content

Commit ce472f1

Browse files
authored
As patterns in offchain code (#94)
1 parent df5ff65 commit ce472f1

File tree

10 files changed

+183
-93
lines changed

10 files changed

+183
-93
lines changed

cabal.project

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ repository cardano-haskell-packages
1515
d4a35cd3121aa00d18544bb0ac01c3e1691d618f462c46129271bccf39f7e8ee
1616

1717
index-state:
18-
, hackage.haskell.org 2025-02-14T16:51:26Z
19-
, cardano-haskell-packages 2025-02-14T16:51:26Z
18+
, hackage.haskell.org 2025-04-15T08:13:08Z
19+
, cardano-haskell-packages 2025-04-11T16:42:25Z
2020

2121
constraints:
2222
plutus-core == 1.40.0.0,
@@ -42,8 +42,8 @@ packages:
4242
source-repository-package
4343
type: git
4444
location: https://github.com/j-mueller/sc-tools
45-
tag: f7d5883efe416afc5ba5e5461ad4115ee9245a9b
46-
--sha256: sha256-bbRmnKWzw6JBaNUY1Lprvg3ryZ3pXxJpUHuOlJKM6Rs=
45+
tag: 100452e6b64200cdffcb2582be07c47e1efebb6b
46+
--sha256: sha256-65swdL2zk1mbqdjten6SIX/2v8tADOX4AhzyE0ocpwY=
4747
subdir:
4848
src/devnet
4949
src/coin-selection

flake.lock

Lines changed: 62 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/regulated-stablecoin/lib/Wst/App.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import Convex.Class (MonadBlockchain, MonadUtxoQuery)
1717
import Data.String (IsString (..))
1818
import Servant.Server (Handler (..))
1919
import Servant.Server qualified as S
20-
import Wst.AppError (AppError (BlockfrostErr))
20+
import Wst.AppError (AppError (..), ProgrammableTokensError (..))
2121
import Wst.Offchain.Env (RuntimeEnv (..))
2222
import Wst.Offchain.Env qualified as Env
2323

@@ -31,7 +31,7 @@ runWstApp :: forall env era a. (Env.HasRuntimeEnv env) => env -> WstApp env era
3131
runWstApp env WstApp{unWstApp} = do
3232
let RuntimeEnv{envBlockfrost} = Env.runtimeEnv env
3333
evalBlockfrostT envBlockfrost (runExceptT (runReaderT unWstApp env)) >>= \case
34-
Left e -> pure (Left $ BlockfrostErr e)
34+
Left e -> pure (Left $ ProgTokensError $ BlockfrostErr e)
3535
Right a -> pure a
3636

3737
{-| Interpret the 'WstApp' in a servant handler
Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,60 @@
1+
{-# LANGUAGE FlexibleInstances #-}
2+
{-# LANGUAGE FunctionalDependencies #-}
3+
{-# LANGUAGE TemplateHaskell #-}
14
{-| Error type for endpoints and queries
25
-}
36
module Wst.AppError(
4-
AppError(..)
7+
-- * Programmable token errors
8+
ProgrammableTokensError(..),
9+
AsProgrammableTokensError(..),
10+
11+
-- * WST App error
12+
AppError(..),
13+
AsAppError(..)
514
) where
615

716
import Blockfrost.Client.Core (BlockfrostError)
8-
import Convex.Class (ValidationError)
17+
import Control.Lens (makeClassyPrisms)
18+
import Convex.Class (AsValidationError (..), ValidationError)
19+
import Convex.CoinSelection (AsBalanceTxError (..), AsCoinSelectionError (..))
920
import Convex.CoinSelection qualified as CoinSelection
1021
import PlutusLedgerApi.V3 (Credential)
1122

12-
data AppError era =
23+
data ProgrammableTokensError =
1324
OperatorNoUTxOs -- ^ The operator does not have any UTxOs
1425
| GlobalParamsNodeNotFound -- ^ The node with the global parameters was not found
15-
| BalancingError (CoinSelection.BalanceTxError era)
1626
| BlockfrostErr BlockfrostError
27+
-- TODO: The following errors are specific to the regulated stablecoin
28+
-- They should be separated out
1729
| NoTokensToSeize -- ^ No tokens to seize
1830
| DuplicateBlacklistNode -- ^ Attempting to add a duplicate blacklist node
1931
| BlacklistNodeNotFound -- ^ Attempting to remove a blacklist node that does not exist
2032
| TransferBlacklistedCredential Credential -- ^ Attempting to transfer funds from a blacklisted address
33+
deriving stock (Show)
34+
35+
makeClassyPrisms ''ProgrammableTokensError
36+
37+
data AppError era =
38+
BalancingError (CoinSelection.BalanceTxError era)
2139
| SubmitError (ValidationError era)
40+
| ProgTokensError ProgrammableTokensError
2241
deriving stock (Show)
42+
43+
makeClassyPrisms ''AppError
44+
45+
instance AsBalanceTxError (AppError era) era where
46+
_BalanceTxError = _BalancingError
47+
48+
instance AsValidationError (AppError era) era where
49+
_ValidationError = _SubmitError
50+
51+
instance AsProgrammableTokensError (AppError era) where
52+
_ProgrammableTokensError = _ProgTokensError
53+
54+
instance AsCoinSelectionError (AppError era) where
55+
_CoinSelectionError = _BalancingError . _CoinSelectionError
56+
57+
instance CoinSelection.AsBalancingError (AppError era) era where
58+
__BalancingError = _BalanceTxError . CoinSelection.__BalancingError
59+
60+
-- CoinSelection.AsCoinSelectionError err, CoinSelection.AsBalancingError err era

src/regulated-stablecoin/lib/Wst/Offchain/BuildTx/Failing.hs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ module Wst.Offchain.BuildTx.Failing(
1414
import Cardano.Api.Experimental (IsEra)
1515
import Cardano.Api.Shelley qualified as C
1616
import Control.Lens (set)
17-
import Control.Monad.Except (MonadError, throwError)
17+
import Control.Monad.Error.Lens (throwing, throwing_)
18+
import Control.Monad.Except (MonadError)
1819
import Control.Monad.Reader (MonadReader, asks)
1920
import Convex.BuildTx (BuildTxT)
2021
import Convex.BuildTx qualified as BuildTx
2122
import Convex.CardanoApi.Lenses qualified as L
2223
import Convex.Class (MonadBlockchain, queryProtocolParameters)
2324
import Convex.CoinSelection qualified as CoinSelection
2425
import Convex.PlutusLedger.V1 (transCredential)
25-
import Convex.Utils (mapError)
2626
import Convex.Utxos (BalanceChanges)
2727
import Convex.Utxos qualified as Utxos
2828
import Convex.Wallet.Operator (returnOutputFor)
2929
import Data.Aeson (FromJSON, ToJSON)
3030
import GHC.Generics (Generic)
31-
import Wst.AppError (AppError (..))
31+
import Wst.AppError (AsProgrammableTokensError (..))
3232
import Wst.Offchain.BuildTx.TransferLogic (FindProofResult (..))
3333
import Wst.Offchain.Env (HasOperatorEnv (..), OperatorEnv (..))
3434
import Wst.Offchain.Query (UTxODat (..))
@@ -43,7 +43,7 @@ data BlacklistedTransferPolicy
4343

4444
{-| Balance a transaction using the operator's funds and return output
4545
-}
46-
balanceTxEnvFailing :: forall era env m. (MonadBlockchain era m, MonadReader env m, HasOperatorEnv era env, MonadError (AppError era) m, C.IsBabbageBasedEra era) => BlacklistedTransferPolicy -> BuildTxT era m (FindProofResult era) -> m (C.BalancedTxBody era, BalanceChanges)
46+
balanceTxEnvFailing :: forall era env err m. (MonadBlockchain era m, MonadReader env m, HasOperatorEnv era env, MonadError err m, C.IsBabbageBasedEra era, AsProgrammableTokensError err, CoinSelection.AsCoinSelectionError err, CoinSelection.AsBalancingError err era) => BlacklistedTransferPolicy -> BuildTxT era m (FindProofResult era) -> m (C.BalancedTxBody era, BalanceChanges)
4747
balanceTxEnvFailing policy btx = do
4848
OperatorEnv{bteOperatorUtxos, bteOperator} <- asks operatorEnv
4949
params <- queryProtocolParameters
@@ -54,14 +54,14 @@ balanceTxEnvFailing policy btx = do
5454
output <- returnOutputFor credential
5555
(balBody, balChanges) <- case r of
5656
CredentialNotBlacklisted{} -> do
57-
mapError BalancingError (CoinSelection.balanceTx mempty output (Utxos.fromApiUtxo bteOperatorUtxos) txBuilder CoinSelection.TrailingChange)
57+
CoinSelection.balanceTx mempty output (Utxos.fromApiUtxo bteOperatorUtxos) txBuilder CoinSelection.TrailingChange
5858
CredentialBlacklisted UTxODat{}
5959
| policy == SubmitFailingTx -> do
6060
-- deliberately set the script validity flag to false
6161
-- this means we will be losing the collateral!
6262
let builder' = txBuilder <> BuildTx.liftTxBodyEndo (set L.txScriptValidity (C.TxScriptValidity C.alonzoBasedEra C.ScriptInvalid))
63-
mapError BalancingError (CoinSelection.balanceTx mempty output (Utxos.fromApiUtxo bteOperatorUtxos) builder' CoinSelection.TrailingChange)
63+
CoinSelection.balanceTx mempty output (Utxos.fromApiUtxo bteOperatorUtxos) builder' CoinSelection.TrailingChange
6464
| otherwise -> do
65-
throwError (TransferBlacklistedCredential (transCredential credential))
66-
NoBlacklistNodes -> throwError BlacklistNodeNotFound
65+
throwing _TransferBlacklistedCredential (transCredential credential)
66+
NoBlacklistNodes -> throwing_ _BlacklistNodeNotFound
6767
pure (balBody, balChanges)

0 commit comments

Comments
 (0)