module Scripts.Lifecycling where import DA.Map qualified as M (empty) import DA.Set qualified as S (empty, fromList, singleton) import Daml.Script -- INTERFACE DEPENDENCIES -- import Daml.Finance.Interface.Instrument.Base.Instrument qualified as Instrument (I) import Daml.Finance.Interface.Lifecycle.Event qualified as Event (I) import Daml.Finance.Interface.Lifecycle.Rule.Claim qualified as Claim (ClaimEffect(..), I) import Daml.Finance.Interface.Lifecycle.Rule.Lifecycle qualified as Lifecycle (Evolve(..), I) import Daml.Finance.Interface.Settlement.Batch qualified as Batch (Settle(..)) import Daml.Finance.Interface.Settlement.Instruction qualified as Instruction (Allocate(..), Approve(..)) import Daml.Finance.Interface.Settlement.Types (Allocation(..), Approval(..)) import Daml.Finance.Interface.Types.Common.Types (Id(..)) import Daml.Finance.Interface.Util.Common (qty) -- IMPLEMENTATION DEPENDENCIES -- import Daml.Finance.Instrument.Token.Instrument (Instrument(..)) import Daml.Finance.Lifecycle.Event.Distribution qualified as Distribution (Event(..)) import Daml.Finance.Lifecycle.Rule.Claim qualified as Claim (Rule(..)) import Daml.Finance.Lifecycle.Rule.Distribution qualified as Distribution (Rule(..)) import Scripts.Settlement (SettlementState(..), runSettlement) -- | Test script that -- 1. executes the `runSettlement` script -- 2. creates a distribution lifecycle rule -- 3. creates a distribution lifecycle event -- 4. lifecycles the distribution event -- 5. processes the lifecycle effect -- 6. settles the distribution runLifecycling : Script() runLifecycling = do -- Execute the `runSettlement` script. Bob now holds 10 tokens in his account. SettlementState{alice , bank , bob , public , aliceAccount , bobAccount , usdInstrument , tokenInstrument , routeProviderCid , settlementFactoryCid , aliceHoldingCid , bobHoldingCid} <- runSettlement -- The bank creates a new version of the token instrument (the "ex-distribution" version). This is -- the version Bob will hold after claiming the effect further down below. -- NEW_VERSION_BEGIN let newTokenInstrument = tokenInstrument with version = "1" now <- getTime tokenInstrumentCid <- toInterfaceContractId @Instrument.I <$> submit bank do createCmd Instrument with depository = bank issuer = bank id = tokenInstrument.id version = "1" description = "Instrument representing units of a generic token" validAsOf = now observers = M.empty -- NEW_VERSION_END -- Create lifecycle rules -- LIFECYCLE_RULES_BEGIN distributionRuleCid <- toInterfaceContractId @Lifecycle.I <$> submit bank do createCmd Distribution.Rule with providers = S.singleton bank lifecycler = bank observers = S.singleton bob id = Id "Lifecycle rule for distribution" description = "Rule contract to lifecycle an instrument following a distribution event" lifecycleClaimRuleCid <- toInterfaceContractId @Claim.I <$> submitMulti [bank, bob] [] do createCmd Claim.Rule with providers = S.fromList [bank, bob] claimers = S.singleton bob settlers = S.singleton bob routeProviderCid settlementFactoryCid netInstructions = False -- LIFECYCLE_RULES_END -- Create cash distribution event -- CREATE_EVENT_BEGIN distributionEventCid <- toInterfaceContractId @Event.I <$> submit bank do createCmd Distribution.Event with providers = S.singleton bank id = Id "DISTRIBUTION" description = "Profit distribution" effectiveTime = now targetInstrument = tokenInstrument newInstrument = newTokenInstrument perUnitDistribution = [qty 0.02 usdInstrument] observers = S.empty -- CREATE_EVENT_END -- Lifecycle distribution event -- LIFECYCLE_EVENT_BEGIN (_, [effectCid]) <- submit bank do exerciseCmd distributionRuleCid Lifecycle.Evolve with eventCid = distributionEventCid observableCids = [] instrument = tokenInstrument -- LIFECYCLE_EVENT_END -- Claim effect -- CLAIM_EVENT_BEGIN result <- submitMulti [bob] [public] do exerciseCmd lifecycleClaimRuleCid Claim.ClaimEffect with claimer = bob holdingCids = [bobHoldingCid] effectCid batchId = Id "DistributionSettlement" let [bobInstructionCid, bankInstructionCid, couponInstructionCid] = result.instructionCids -- CLAIM_EVENT_END -- EFFECT_SETTLEMENT_BEGIN -- Allocate instruction (bobInstructionCid, _) <- submit bob do exerciseCmd bobInstructionCid Instruction.Allocate with actors = S.singleton bob allocation = Pledge bobHoldingCid (bankInstructionCid, _) <- submit bank do exerciseCmd bankInstructionCid Instruction.Allocate with actors = S.singleton bank allocation = CreditReceiver (couponInstructionCid, _) <- submit bank do exerciseCmd couponInstructionCid Instruction.Allocate with actors = S.singleton bank allocation = CreditReceiver -- Approve instruction bobInstructionCid <- submit bank do exerciseCmd bobInstructionCid Instruction.Approve with actors = S.singleton bank approval = DebitSender bankInstructionCid <- submit bob do exerciseCmd bankInstructionCid Instruction.Approve with actors = S.singleton bob approval = TakeDelivery bobAccount couponInstructionCid <- submit bob do exerciseCmd couponInstructionCid Instruction.Approve with actors = S.singleton bob approval = TakeDelivery bobAccount -- Settle batch submitMulti [bob] [public] do exerciseCmd result.batchCid Batch.Settle with actors = S.singleton bob -- EFFECT_SETTLEMENT_END pure ()