33module BotPlutusInterface.Balance (
44 balanceTxStep ,
55 balanceTxIO ,
6+ withFee ,
67) where
78
89import BotPlutusInterface.CardanoCLI qualified as CardanoCLI
@@ -89,7 +90,7 @@ balanceTxIO pabConf ownPkh unbalancedTx =
8990 (balancedTx, minUtxos) <- loop utxoIndex privKeys [] preBalancedTx
9091
9192 -- Check if we have Ada change
92- let adaChange = getAdaChange utxoIndex (lovelaceValue $ txFee balancedTx) balancedTx
93+ let adaChange = getAdaChange utxoIndex balancedTx
9394 -- If we have no change UTxO, but we do have change, we need to add an output for it
9495 -- We'll add a minimal output, run the loop again so it gets minUTxO, then update change
9596 balancedTxWithChange <-
@@ -107,7 +108,7 @@ balanceTxIO pabConf ownPkh unbalancedTx =
107108 else pure balancedTx
108109
109110 -- Get the updated change, add it to the tx
110- let finalAdaChange = getAdaChange utxoIndex (lovelaceValue $ txFee balancedTxWithChange) balancedTxWithChange
111+ let finalAdaChange = getAdaChange utxoIndex balancedTxWithChange
111112 fullyBalancedTx = addAdaChange ownPkh finalAdaChange balancedTxWithChange
112113
113114 -- finally, we must update the signatories
@@ -131,7 +132,7 @@ balanceTxIO pabConf ownPkh unbalancedTx =
131132
132133 -- Calculate fees by pre-balancing the tx, building it, and running the CLI on result
133134 txWithoutFees <-
134- hoistEither $ balanceTxStep minUtxos 0 utxoIndex ownPkh tx
135+ hoistEither $ balanceTxStep minUtxos utxoIndex ownPkh $ tx `withFee` 0
135136
136137 lift $ createDirectoryIfMissing @ w False (Text. unpack pabConf. pcTxFileDir)
137138 newEitherT $ CardanoCLI. buildTx @ w pabConf privKeys txWithoutFees
@@ -140,13 +141,14 @@ balanceTxIO pabConf ownPkh unbalancedTx =
140141 lift $ printLog @ w Debug $ " Fees: " ++ show fees
141142
142143 -- Rebalance the initial tx with the above fees
143- balancedTx <- hoistEither $ balanceTxStep minUtxos fees utxoIndex ownPkh tx
144+ balancedTx <- hoistEither $ balanceTxStep minUtxos utxoIndex ownPkh $ tx `withFee` fees
144145
145- let balanceTxWithFees = balancedTx {txFee = Ada. lovelaceValueOf fees}
146+ if balancedTx == tx
147+ then pure (balancedTx, minUtxos)
148+ else loop utxoIndex privKeys minUtxos balancedTx
146149
147- if balanceTxWithFees == tx
148- then pure (balanceTxWithFees, minUtxos)
149- else loop utxoIndex privKeys minUtxos balanceTxWithFees
150+ withFee :: Tx -> Integer -> Tx
151+ withFee tx fee = tx {txFee = Ada. lovelaceValueOf fee}
150152
151153calculateMinUtxos ::
152154 forall (w :: Type ) (effs :: [Type -> Type ]).
@@ -160,20 +162,20 @@ calculateMinUtxos pabConf datums txOuts =
160162
161163balanceTxStep ::
162164 [(TxOut , Integer )] ->
163- Integer ->
164165 Map TxOutRef TxOut ->
165166 PubKeyHash ->
166167 Tx ->
167168 Either Text Tx
168- balanceTxStep minUtxos fees utxos ownPkh tx =
169+ balanceTxStep minUtxos utxos ownPkh tx =
169170 Right (addLovelaces minUtxos tx)
170- >>= balanceTxIns utxos fees
171- >>= handleNonAdaChange ownPkh utxos fees
171+ >>= balanceTxIns utxos
172+ >>= handleNonAdaChange ownPkh utxos
172173
173174-- | Get change value of a transaction, taking inputs, outputs, mint and fees into account
174- getChange :: Map TxOutRef TxOut -> Integer -> Tx -> Value
175- getChange utxos fees tx =
176- let txInRefs = map Tx. txInRef $ Set. toList $ txInputs tx
175+ getChange :: Map TxOutRef TxOut -> Tx -> Value
176+ getChange utxos tx =
177+ let fees = lovelaceValue $ txFee tx
178+ txInRefs = map Tx. txInRef $ Set. toList $ txInputs tx
177179 inputValue = mconcat $ map Tx. txOutValue $ mapMaybe (`Map.lookup` utxos) txInRefs
178180 outputValue = mconcat $ map Tx. txOutValue $ txOutputs tx
179181 nonMintedOutputValue = outputValue `minus` txMint tx
@@ -183,11 +185,11 @@ getChange utxos fees tx =
183185lovelaceValue :: Value -> Integer
184186lovelaceValue = flip Value. assetClassValueOf $ Value. assetClass " " " "
185187
186- getAdaChange :: Map TxOutRef TxOut -> Integer -> Tx -> Integer
187- getAdaChange utxos fees = lovelaceValue . getChange utxos fees
188+ getAdaChange :: Map TxOutRef TxOut -> Tx -> Integer
189+ getAdaChange utxos = lovelaceValue . getChange utxos
188190
189- getNonAdaChange :: Map TxOutRef TxOut -> Integer -> Tx -> Value
190- getNonAdaChange utxos fees = Ledger. noAdaValue . getChange utxos fees
191+ getNonAdaChange :: Map TxOutRef TxOut -> Tx -> Value
192+ getNonAdaChange utxos = Ledger. noAdaValue . getChange utxos
191193
192194-- | Getting the necessary utxos to cover the fees for the transaction
193195collectTxIns :: Set TxIn -> Map TxOutRef TxOut -> Value -> Either Text (Set TxIn )
@@ -245,13 +247,13 @@ addLovelaces minLovelaces tx =
245247 $ txOutputs tx
246248 in tx {txOutputs = lovelacesAdded}
247249
248- balanceTxIns :: Map TxOutRef TxOut -> Integer -> Tx -> Either Text Tx
249- balanceTxIns utxos fees tx = do
250+ balanceTxIns :: Map TxOutRef TxOut -> Tx -> Either Text Tx
251+ balanceTxIns utxos tx = do
250252 let txOuts = Tx. txOutputs tx
251253 nonMintedValue = mconcat (map Tx. txOutValue txOuts) `minus` txMint tx
252254 minSpending =
253255 mconcat
254- [ Ada. lovelaceValueOf fees
256+ [ txFee tx
255257 , nonMintedValue
256258 ]
257259 txIns <- collectTxIns (txInputs tx) utxos minSpending
@@ -274,10 +276,10 @@ addTxCollaterals utxos tx = do
274276 filterAdaOnly = Map. filter (isAdaOnly . txOutValue)
275277
276278-- | Ensures all non ada change goes back to user
277- handleNonAdaChange :: PubKeyHash -> Map TxOutRef TxOut -> Integer -> Tx -> Either Text Tx
278- handleNonAdaChange ownPkh utxos fees tx =
279+ handleNonAdaChange :: PubKeyHash -> Map TxOutRef TxOut -> Tx -> Either Text Tx
280+ handleNonAdaChange ownPkh utxos tx =
279281 let changeAddr = Ledger. pubKeyHashAddress (Ledger. PaymentPubKeyHash ownPkh) Nothing
280- nonAdaChange = getNonAdaChange utxos fees tx
282+ nonAdaChange = getNonAdaChange utxos tx
281283 outputs =
282284 case partition ((==) changeAddr . Tx. txOutAddress) $ txOutputs tx of
283285 ([] , txOuts) ->
0 commit comments