-- Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. -- SPDX-License-Identifier: Apache-2.0 -- | This module defines the `Allocation` interface and supporting types. -- -- Contracts implementing the `Allocation` interface represent a reservation of -- assets to transfer them as part of an atomic on-ledger settlement requested -- by an app. module Splice.Api.Token.AllocationV1 where import Splice.Api.Token.MetadataV1 import Splice.Api.Token.HoldingV1 (Holding, InstrumentId) -- | A generic type to refer to data defined within an app. -- The interpretation of such a reference is app specific, but SHOULD be unambiguous within the context of the app. data Reference = Reference with id : Text -- ^ The key that identifies the data. Can be set to the empty string if the contract-id is provided and is sufficient. cid : Optional AnyContractId -- ^ Optional contract-id to use for referring to contracts. -- -- This field is there for technical reasons, as contract-ids cannot be converted to text from within Daml, -- which is due to their full textual representation being only known after transactions have been prepared. deriving (Show, Eq) -- | The minimal set of information about a settlement that an app would like to execute. data SettlementInfo = SettlementInfo with executor : Party -- ^ The party that is responsible for executing the settlement. settlementRef : Reference -- ^ Reference to the settlement that app would like to execute. requestedAt : Time -- ^ When the settlement was requested. Provided for display and debugging purposes, -- but SHOULD be in the past. allocateBefore : Time -- ^ Until when (exclusive) the senders are given time to allocate their assets. -- This field has a particular relevance with respect to instrument versioning / corporate -- actions, in that the settlement pertains to the instrument version resulting from the -- processing of all corporate actions falling strictly before the `allocateBefore` time. settleBefore : Time -- ^ Until when (exclusive) the executor is given time to execute the settlement. -- -- SHOULD be strictly after `allocateBefore`. meta : Metadata -- ^ Additional metadata about the settlement, used for extensibility. deriving (Show, Eq) -- | A specification of a transfer of holdings between two parties for the -- purpose of a settlement, which often requires the atomic execution of multiple legs. data TransferLeg = TransferLeg with sender : Party -- ^ The sender of the transfer. receiver : Party -- ^ The receiver of the transfer. amount : Decimal -- ^ The amount to transfer. instrumentId : InstrumentId -- ^ The instrument identifier. meta : Metadata -- ^ Additional metadata about the transfer leg, used for extensibility. deriving (Eq, Ord, Show) -- | The specification of an allocation of assets to a specific leg of a settlement. -- -- In contrast to an `AllocationView` this just specifies what should be allocated, -- but not the holdings that are backing the allocation. data AllocationSpecification = AllocationSpecification with settlement : SettlementInfo -- ^ The settlement for whose execution the assets are being allocated. transferLegId : Text -- ^ A unique identifer for the transfer leg within the settlement. transferLeg : TransferLeg -- ^ The transfer for which the assets are being allocated. deriving (Show, Eq) -- | View of a funded allocation of assets to a specific leg of a settlement. data AllocationView = AllocationView with allocation : AllocationSpecification -- ^ The settlement for whose execution the assets are being allocated. holdingCids : [ContractId Holding] -- ^ The holdings that are backing this allocation. -- -- Provided so that that wallets can correlate the allocation with the -- holdings. -- -- MAY be empty for registries that do not represent their holdings on-ledger. meta : Metadata -- ^ Additional metadata specific to the allocation, used for extensibility. deriving (Show, Eq) -- Allocation ------------------------ -- | Convenience function to refer to the union of sender, receiver, and -- executor of the settlement, which jointly control the execution of the -- allocation. allocationControllers : AllocationView -> [Party] allocationControllers AllocationView{..} = [allocation.settlement.executor, allocation.transferLeg.sender, allocation.transferLeg.receiver] -- | A contract representing an allocation of some amount of aasset holdings to -- a specific leg of a settlement. interface Allocation where viewtype AllocationView allocation_executeTransferImpl : ContractId Allocation -> Allocation_ExecuteTransfer -> Update Allocation_ExecuteTransferResult allocation_cancelImpl : ContractId Allocation -> Allocation_Cancel -> Update Allocation_CancelResult allocation_withdrawImpl : ContractId Allocation -> Allocation_Withdraw -> Update Allocation_WithdrawResult choice Allocation_ExecuteTransfer : Allocation_ExecuteTransferResult -- ^ Execute the transfer of the allocated assets. Intended to be used to execute the settlement. -- This choice SHOULD succeed provided the `settlement.settleBefore` deadline has not yet passed. with extraArgs : ExtraArgs -- ^ Additional context required in order to exercise the choice. controller allocationControllers (view this) do allocation_executeTransferImpl this self arg choice Allocation_Cancel : Allocation_CancelResult -- ^ Cancel the allocation. Requires authorization from sender, receiver, and -- executor. -- -- Typically this authorization is granted by sender and receiver to the -- executor as part of the contract coordinating the settlement, so that -- that the executor can release the allocated assets early in case the -- settlement is aborted or it has definitely failed. with extraArgs : ExtraArgs -- ^ Additional context required in order to exercise the choice. controller allocationControllers (view this) do allocation_cancelImpl this self arg choice Allocation_Withdraw : Allocation_WithdrawResult -- ^ Withdraw the allocated assets. Used by the sender to withdraw the assets before settlement -- was completed. This SHOULD not fail settlement if the sender has still time to allocate the -- assets again; i.e., the `settlement.allocateBefore` deadline has not yet passed. with extraArgs : ExtraArgs -- ^ Additional context required in order to exercise the choice. controller (view this).allocation.transferLeg.sender do allocation_withdrawImpl this self arg -- Result types --------------- -- | The result of the `Allocation_ExecuteTransfer` choice. data Allocation_ExecuteTransferResult = Allocation_ExecuteTransferResult with senderHoldingCids : [ContractId Holding] -- ^ The holdings that were created for the sender. Can be used to return -- "change" to the sender if required. receiverHoldingCids : [ContractId Holding] -- ^ The holdings that were created for the receiver. meta : Metadata -- ^ Additional metadata specific to the transfer instruction, used for extensibility. deriving (Show, Eq) -- | The result of the `Allocation_Cancel` choice. data Allocation_CancelResult = Allocation_CancelResult with senderHoldingCids : [ContractId Holding] -- ^ The holdings that were released back to the sender. meta : Metadata -- ^ Additional metadata specific to the allocation, used for extensibility. deriving (Show, Eq) -- | The result of the `Allocation_Withdraw` choice. data Allocation_WithdrawResult = Allocation_WithdrawResult with senderHoldingCids : [ContractId Holding] -- ^ The holdings that were released back to the sender. meta : Metadata -- ^ Additional metadata specific to the allocation, used for extensibility. deriving (Show, Eq)