Skip to content

Commit

Permalink
feat: add singular utxo indexer one to many
Browse files Browse the repository at this point in the history
  • Loading branch information
hadelive committed Apr 24, 2024
1 parent 53f9d57 commit 6065627
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
1 change: 1 addition & 0 deletions plutarch-design-pattern.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ library
Plutarch.TxLevelMinter
Plutarch.Utils
Plutarch.ValidityRangeNormalization
Plutarch.SingularUTxOIndexerOneToMany

build-depends:
, aeson
Expand Down
2 changes: 2 additions & 0 deletions src/Plutarch/MerkelizedValidator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
module Plutarch.MerkelizedValidator (
spend,
withdraw,
WithdrawRedeemer (..),
PWithdrawRedeemer (..),
) where

import Plutarch.Api.V1 qualified as V1
Expand Down
3 changes: 3 additions & 0 deletions src/Plutarch/SingularUTxOIndexer.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module Plutarch.SingularUTxOIndexer (
spend,
SpendRedeemer (..),
PSpendRedeemer (..),
) where

import Plutarch.Api.V2 (
Expand Down Expand Up @@ -31,6 +33,7 @@ newtype PSpendRedeemer (s :: S)

instance DerivePlutusType PSpendRedeemer where type DPTStrat _ = PlutusTypeData
instance PTryFrom PData PSpendRedeemer

spend :: Term s (PTxOut :--> PTxOut :--> PBool) -> Term s PValidator
spend f =
plam $ \_datum redeemer ctx -> unTermCont $ do
Expand Down
68 changes: 68 additions & 0 deletions src/Plutarch/SingularUTxOIndexerOneToMany.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
module Plutarch.SingularUTxOIndexerOneToMany (
spend,
SpendRedeemer (..),
PSpendRedeemer (..),
) where

import Plutarch.Api.V2 (
PScriptPurpose (..),
PTxOut,
PValidator,
)
import Plutarch.Builtin (pasInt)
import Plutarch.DataRepr (PDataFields)
import Plutarch.Prelude
import Plutarch.Unsafe (punsafeCoerce)
import PlutusTx (BuiltinData)
import "liqwid-plutarch-extra" Plutarch.Extra.TermCont (
pletC,
pletFieldsC,
pmatchC,
)

data SpendRedeemer = SpendRedeemer
{ inIx :: BuiltinData
, outIxs :: [BuiltinData]
}
deriving stock (Generic, Eq, Show)

newtype PSpendRedeemer (s :: S)
= PSpendRedeemer (Term s (PDataRecord '["inIx" ':= PData, "outIxs" ':= PBuiltinList PData]))
deriving stock (Generic)
deriving anyclass (PlutusType, PIsData, PDataFields, PShow)

instance DerivePlutusType PSpendRedeemer where type DPTStrat _ = PlutusTypeData
instance PTryFrom PData PSpendRedeemer

spend :: Term s (PTxOut :--> PBool)
-> Term s (PTxOut :--> PTxOut :--> PBool)
-> Term s (PBuiltinList PTxOut :--> PInteger :--> PBool)
-> Term s PValidator
spend inputValidator inputOutputValidator collectiveOutputValidator =
plam $ \_datum redeemer ctx -> unTermCont $ do
let red = punsafeCoerce @_ @_ @PSpendRedeemer redeemer
redF <- pletFieldsC @'["indx", "outIxs"] red
ctxF <- pletFieldsC @'["txInfo", "purpose"] ctx
PSpending ownRef' <- pmatchC ctxF.purpose
ownRef <- pletC $ pfield @"_0" # ownRef'
txInfoF <- pletFieldsC @'["inputs", "outputs"] ctxF.txInfo
let inIx = pasInt # redF.inIx
outIxs = pmap # pasInt # redF.outIxs
(_, outTxOuts, outputCount) =
pfoldr #
plan (\(curIdx (prevIdx, acc, count) -> pif
(curIdx #< prevIdx)
(curIdx, pconcat # acc # psingleton (pelemAt @PBuiltinList # curIdx # txInfoF.outputs), count + 1))
perror
) #
(P.length # outputs, [], 0) #
outIxs

outOutput = pelemAt @PBuiltinList # outIdx # txInfoF.outputs
inInputF <- pletFieldsC @'["outRef", "resolved"] (pelemAt @PBuiltinList # inIx # txInfoF.inputs)
return $
popaque $
pif
(ptraceIfFalse "Indicated input must match the spending one" (ownRef #== inInputF.outRef))
(inputOutputValidator # inInputF.resolved # outOutput)
perror

0 comments on commit 6065627

Please sign in to comment.