@@ -56,7 +56,7 @@ depositTx networkId headId commitBlueprintTx upperSlot deadline amount tokens =
56
56
57
57
utxoToDeposit = utxoToDeposit' <> tokensToDepositUTxO
58
58
59
- tokensToDepositUTxO = undefined -- pickTokensToDeposit leftoverUTxO' tokens
59
+ tokensToDepositUTxO = pickTokensToDeposit leftoverUTxO' tokens
60
60
leftoverOutput =
61
61
let leftoverUTxO = (leftoverUTxO' `withoutUTxO` tokensToDepositUTxO)
62
62
in if UTxO. null leftoverUTxO
@@ -72,57 +72,41 @@ depositTx networkId headId commitBlueprintTx upperSlot deadline amount tokens =
72
72
depositInputs = (,BuildTxWith $ KeyWitness KeyWitnessForSpending ) <$> depositInputsList
73
73
74
74
pickTokensToDeposit :: UTxO -> Map PolicyId PolicyAssets -> UTxO
75
- pickTokensToDeposit leftoverUTxO depositTokens =
76
- if null depositTokens
77
- then mempty
78
- else
79
- let x = concatMap (go mempty ) (UTxO. toList leftoverUTxO)
80
- in combineTxOutAssets x
75
+ pickTokensToDeposit leftoverUTxO depositTokens
76
+ | Map. null depositTokens = mempty
77
+ | otherwise = UTxO. fromList picked -- Assuming UTxO.fromList :: [(TxIn, TxOut CtxUTxO)] -> UTxO; adjust if needed.
81
78
where
82
- go :: [(TxIn , TxOut CtxUTxO )] -> (TxIn , TxOut CtxUTxO ) -> [(TxIn , TxOut CtxUTxO )]
83
- go defVal (i, o) = do
84
- let outputAssets = valueToPolicyAssets $ txOutValue o
85
- providedUTxOAssets = concatMap (\ (pid, PolicyAssets a) -> (\ (x, y) -> (pid, x, y)) <$> toList a) (Map. toList outputAssets)
86
- (k, PolicyAssets v) <- Map. assocs depositTokens
87
-
88
- if k `elem` Map. keys outputAssets
89
- then do
90
- (wantedAssetName, wantedAssetVal) <- Map. toList v
91
- case find (\ (pid, n, val) -> pid == k && wantedAssetName == n && wantedAssetVal <= val) providedUTxOAssets of
92
- Nothing -> defVal
93
- Just (pid', _an, _av) -> do
94
- let newValue = fromList [(AssetId pid' wantedAssetName, wantedAssetVal)]
95
- defVal <> [(i, mkTxOutValueKeepingLovelace o newValue)]
96
- else defVal
97
-
98
- combineTxOutAssets :: [(TxIn , TxOut CtxUTxO )] -> UTxO. UTxO
99
- combineTxOutAssets =
100
- foldl'
101
- ( \ finalUTxO (i, o) ->
102
- case UTxO. findBy (existingTxId i) finalUTxO of
103
- Nothing -> finalUTxO <> UTxO. singleton i o
104
- Just (existingInput, existingOutput) ->
105
- let val = valueToPolicyAssets $ txOutValue o
106
- in UTxO. singleton existingInput (addTxOutValue existingOutput val)
107
- )
108
- mempty
109
-
110
- existingTxId :: TxIn -> (TxIn , TxOut CtxUTxO ) -> Bool
111
- existingTxId txIn (a, _) = a == txIn
112
-
113
- mkTxOutValueKeepingLovelace :: TxOut ctx -> Value -> TxOut ctx
114
- mkTxOutValueKeepingLovelace (TxOut addr val datum refScript) newValue =
115
- TxOut addr (lovelaceToValue (selectLovelace val) <> newValue) datum refScript
116
-
117
- addTxOutValue :: TxOut ctx -> Map PolicyId PolicyAssets -> TxOut ctx
118
- addTxOutValue (TxOut addr val datum refScript) newAssets =
119
- TxOut addr (lovelaceToValue (selectLovelace val) <> assetsToVal (valueToPolicyAssets val) <> assetsToVal newAssets) datum refScript
79
+ -- Build list of (TxIn, new TxOut) where new TxOut has original lovelace + exact required quantities of matched assets.
80
+ picked :: [(TxIn , TxOut CtxUTxO )]
81
+ picked =
82
+ [ (i, mkTxOutValueKeepingLovelace o newValue)
83
+ | (i, o) <- UTxO. toList leftoverUTxO
84
+ , let outputAssets = valueToPolicyAssets (txOutValue o) -- Map PolicyId PolicyAssets from this TxOut.
85
+ , let pickedPolicyAssets = pickMatchedAssets outputAssets depositTokens -- Map PolicyId PolicyAssets with matched.
86
+ , not (Map. null pickedPolicyAssets)
87
+ , let newValue = foldMap (uncurry policyAssetsToValue) (Map. toList pickedPolicyAssets)
88
+ ]
89
+
90
+ -- For a given output's assets and the required depositTokens, build a map of matched policies/assets (exact required qty).
91
+ pickMatchedAssets :: Map PolicyId PolicyAssets -> Map PolicyId PolicyAssets -> Map PolicyId PolicyAssets
92
+ pickMatchedAssets outputAssets = Map. foldrWithKey go mempty
120
93
where
121
- assetsToVal :: Map PolicyId PolicyAssets -> Value
122
- assetsToVal m = foldMap (uncurry policyAssetsToValue) $ toList m
123
-
124
- bumpIndex :: TxIn -> TxIn
125
- bumpIndex (TxIn i (TxIx n)) = TxIn i (TxIx $ n + 1 )
94
+ go :: PolicyId -> PolicyAssets -> Map PolicyId PolicyAssets -> Map PolicyId PolicyAssets
95
+ go pid (PolicyAssets requiredAssets) acc = case Map. lookup pid outputAssets of
96
+ Nothing -> acc
97
+ Just (PolicyAssets availAssets) ->
98
+ let matchedAssets = Map. foldrWithKey (matchAsset availAssets) mempty requiredAssets
99
+ in if Map. null matchedAssets then acc else Map. insert pid (PolicyAssets matchedAssets) acc
100
+
101
+ matchAsset :: Map AssetName Quantity -> AssetName -> Quantity -> Map AssetName Quantity -> Map AssetName Quantity
102
+ matchAsset availAssets name reqQty matched = case Map. lookup name availAssets of
103
+ Just availQty | reqQty <= availQty -> Map. insert name reqQty matched
104
+ _ -> matched
105
+
106
+ -- Helper to create TxOut with original lovelace + new value (unchanged from original).
107
+ mkTxOutValueKeepingLovelace :: TxOut ctx -> Value -> TxOut ctx
108
+ mkTxOutValueKeepingLovelace (TxOut addr val datum refScript) newValue =
109
+ TxOut addr (lovelaceToValue (selectLovelace val) <> newValue) datum refScript
126
110
127
111
mkDepositOutput ::
128
112
NetworkId ->
0 commit comments