@@ -9,7 +9,7 @@ module Wst.Offchain.BuildTx.TransferLogic
99 seizeSmartTokens ,
1010 initBlacklist ,
1111 insertBlacklistNode ,
12- spendBlacklistOutput ,
12+ removeBlacklistNode ,
1313 paySmartTokensToDestination ,
1414 registerTransferScripts ,
1515 )
@@ -36,7 +36,7 @@ import Convex.Utxos (UtxoSet (UtxoSet))
3636import Convex.Wallet (selectMixedInputsCovering )
3737import Data.Foldable (maximumBy )
3838import Data.Function (on )
39- import Data.List (nub , sort )
39+ import Data.List (find , nub , sort )
4040import Data.Monoid (Last (.. ))
4141import GHC.Exts (IsList (.. ))
4242import PlutusLedgerApi.Data.V3 (Credential (.. ), PubKeyHash (PubKeyHash ),
@@ -46,7 +46,7 @@ import SmartTokens.Contracts.ExampleTransferLogic (BlacklistProof (..))
4646import SmartTokens.Types.ProtocolParams
4747import SmartTokens.Types.PTokenDirectory (BlacklistNode (.. ),
4848 DirectorySetNode (.. ))
49- import Wst.AppError (AppError (DuplicateBlacklistNode , TransferBlacklistedCredential ))
49+ import Wst.AppError (AppError (BlacklistNodeNotFound , DuplicateBlacklistNode , TransferBlacklistedCredential ))
5050import Wst.Offchain.BuildTx.ProgrammableLogic (issueProgrammableToken ,
5151 seizeProgrammableToken ,
5252 transferProgrammableToken )
@@ -135,13 +135,48 @@ insertBlacklistNode cred blacklistNodes = Utils.inBabbage @era $ do
135135 opPkh <- asks (fst . Env. bteOperator . Env. operatorEnv)
136136 addRequiredSignature opPkh
137137
138- spendBlacklistOutput :: forall era env m . (MonadReader env m , Env. HasOperatorEnv era env , Env. HasTransferLogicEnv env , C. IsBabbageBasedEra era , C. HasScriptLanguageInEra C. PlutusScriptV3 era , MonadBuildTx era m ) => C. TxIn -> m ()
139- spendBlacklistOutput txin = Utils. inBabbage @ era $ do
140- spendingScript <- asks (Env. tleBlacklistSpendingScript . Env. transferLogicEnv)
141- spendPlutusInlineDatum txin spendingScript ()
138+ removeBlacklistNode :: forall era env m . (MonadReader env m , Env. HasOperatorEnv era env , Env. HasTransferLogicEnv env , C. IsBabbageBasedEra era , C. HasScriptLanguageInEra C. PlutusScriptV3 era , MonadBuildTx era m , MonadError (AppError era ) m ) => C. PaymentCredential -> [UTxODat era BlacklistNode ]-> m ()
139+ removeBlacklistNode cred blacklistNodes = Utils. inBabbage @ era $ do
142140 opPkh <- asks (fst . Env. bteOperator . Env. operatorEnv)
141+ blacklistSpendingScript <- asks (Env. tleBlacklistSpendingScript . Env. transferLogicEnv)
142+ blacklistMintingScript <- asks (Env. tleBlacklistMintingScript . Env. transferLogicEnv)
143+ blacklistPolicyId <- asks (Env. blacklistNodePolicyId . Env. transferLogicEnv)
144+
145+ -- find node to remove
146+ UTxODat {uIn = delNodeRef, uOut = (C. TxOut _delAddr delOutVal _ _), uDatum = delNodeDatum}
147+ <- maybe (throwError BlacklistNodeNotFound ) pure $ find ((== unwrapCredential (transCredential cred)) . blnKey . uDatum) blacklistNodes
148+
149+
150+ let expectedAssetName = C. AssetName $ case transCredential cred of
151+ PubKeyCredential (PubKeyHash s) -> PlutusTx. fromBuiltin s
152+ ScriptCredential (ScriptHash s) -> PlutusTx. fromBuiltin s
153+
154+ v = C. selectAsset (C. txOutValueToValue delOutVal) (C. AssetId blacklistPolicyId expectedAssetName)
155+
156+ when (v /= 1 ) $ error " Unexpected blacklist node token quantity. Head node should not be deleted"
157+
158+ -- find the node to update to point to the node after the node to remove
159+ let UTxODat {uIn = prevNodeRef,uOut = (C. TxOut prevAddr prevVal _ _), uDatum = prevNode} =
160+ maximumBy (compare `on` (blnKey . uDatum)) $
161+ filter ((< unwrapCredential (transCredential cred)) . blnKey . uDatum) blacklistNodes
162+
163+ -- update the previous node to point to the node after the node to remove
164+ updatedPrevNode = prevNode {blnNext= blnNext delNodeDatum}
165+ updatedPrevNodeDatum = C. TxOutDatumInline C. babbageBasedEra $ C. toHashableScriptData updatedPrevNode
166+ updatedPrevNodeOutput = C. TxOut prevAddr prevVal updatedPrevNodeDatum C. ReferenceScriptNone
167+
168+
169+ -- spend the node to remove
170+ spendPlutusInlineDatum delNodeRef blacklistSpendingScript ()
171+ -- set previous node output
172+ spendPlutusInlineDatum prevNodeRef blacklistSpendingScript ()
173+ -- set previous node output
174+ prependTxOut updatedPrevNodeOutput
175+ -- burn the removed node blacklist token
176+ mintPlutus blacklistMintingScript () expectedAssetName (- 1 )
143177 addRequiredSignature opPkh
144178
179+
145180{-| Add a smart token output that locks the given value,
146181addressed to the payment credential
147182-}
0 commit comments