mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 09:17:43 +03:00
update daml finance quickstarter (#16899)
This commit is contained in:
parent
943e140bbb
commit
ab6a85a0a0
173
templates/quickstart-finance/daml/Scripts/Holding.daml
Normal file
173
templates/quickstart-finance/daml/Scripts/Holding.daml
Normal file
@ -0,0 +1,173 @@
|
||||
module Scripts.Holding where
|
||||
|
||||
import DA.Map (empty, fromList)
|
||||
import DA.Set (singleton)
|
||||
import Daml.Script
|
||||
|
||||
-- INTERFACE DEPENDENCIES --
|
||||
import Daml.Finance.Interface.Account.Factory qualified as Account (F)
|
||||
import Daml.Finance.Interface.Holding.Base qualified as Holding (I)
|
||||
import Daml.Finance.Interface.Holding.Factory qualified as Holding (F)
|
||||
import Daml.Finance.Interface.Instrument.Base.Instrument qualified as Instrument (I)
|
||||
import Daml.Finance.Interface.Types.Common.Types (AccountKey, Id(..), InstrumentKey(..))
|
||||
|
||||
-- IMPLEMENTATION DEPENDENCIES --
|
||||
import Daml.Finance.Account.Account qualified as Account (Factory(..))
|
||||
import Daml.Finance.Holding.Fungible qualified as Fungible (Factory(..), Fungible(..))
|
||||
import Daml.Finance.Instrument.Token.Instrument (Instrument(..))
|
||||
|
||||
import Workflow.CreateAccount qualified as CreateAccount
|
||||
import Workflow.CreditAccount qualified as CreditAccount
|
||||
|
||||
-- | Helper container used to transfer state from one script to another.
|
||||
data HoldingState = HoldingState
|
||||
with
|
||||
alice : Party
|
||||
bank : Party
|
||||
bob : Party
|
||||
public : Party
|
||||
aliceAccount : AccountKey
|
||||
bobAccount : AccountKey
|
||||
cashInstrument : InstrumentKey
|
||||
holdingFactoryCid : ContractId Holding.F
|
||||
aliceCashHoldingCid : ContractId Holding.I
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- | Test script that
|
||||
-- 1. creates an account for Alice and Bob at the Bank
|
||||
-- 2. issues a cash instrument
|
||||
-- 3. credits a cash holding to Alice in her bank account
|
||||
runHolding : Script HoldingState
|
||||
runHolding = do
|
||||
|
||||
-- Allocate parties
|
||||
[alice, bank, bob, public] <- mapA createParty ["Alice", "Bank", "Bob", "Public"]
|
||||
|
||||
-- Account Factory (it is used by the bank to create accounts)
|
||||
-- CREATE_ACCOUNT_FACTORY_BEGIN
|
||||
accountFactoryCid <- toInterfaceContractId @Account.F <$> submit bank do
|
||||
createCmd Account.Factory with provider = bank; observers = empty
|
||||
-- CREATE_ACCOUNT_FACTORY_END
|
||||
|
||||
-- Holding Factory (it is used by the bank to create holdings with the desired implementation)
|
||||
-- CREATE_HOLDING_FACTORY_BEGIN
|
||||
holdingFactoryCid <- toInterfaceContractId @Holding.F <$> submit bank do
|
||||
createCmd Fungible.Factory with
|
||||
provider = bank
|
||||
observers = fromList [("PublicObserver", singleton public )]
|
||||
-- CREATE_HOLDING_FACTORY_END
|
||||
|
||||
-- Alice and Bob setup account @Bank
|
||||
-- SETUP_ALICE_ACCOUNT_BEGIN
|
||||
aliceRequestCid <- submit alice do
|
||||
createCmd CreateAccount.Request with owner = alice; custodian = bank
|
||||
aliceAccount <- submit bank do
|
||||
exerciseCmd aliceRequestCid CreateAccount.Accept with
|
||||
label = "Alice@Bank"
|
||||
description = "Account of Alice at Bank"
|
||||
accountFactoryCid = accountFactoryCid
|
||||
holdingFactoryCid = holdingFactoryCid
|
||||
observers = []
|
||||
-- SETUP_ALICE_ACCOUNT_END
|
||||
|
||||
bobRequestCid <- submit bob do createCmd CreateAccount.Request with owner = bob; custodian = bank
|
||||
bobAccount <- submit bank do
|
||||
exerciseCmd bobRequestCid CreateAccount.Accept with
|
||||
label = "Bob@Bank"
|
||||
description = "Account of Bob at Bank"
|
||||
accountFactoryCid = accountFactoryCid
|
||||
holdingFactoryCid = holdingFactoryCid
|
||||
observers = [alice]
|
||||
|
||||
-- Bank creates the cash instrument
|
||||
-- ISSUE_CASH_INSTRUMENT_BEGIN
|
||||
let
|
||||
instrumentId = Id "USD"
|
||||
instrumentVersion = "0"
|
||||
instrumentKey = InstrumentKey with
|
||||
issuer = bank
|
||||
depository = bank
|
||||
id = instrumentId
|
||||
version = instrumentVersion
|
||||
now <- getTime
|
||||
|
||||
cashInstrumentCid <- toInterfaceContractId @Instrument.I <$> submit bank do
|
||||
createCmd Instrument with
|
||||
depository = bank
|
||||
issuer = bank
|
||||
id = instrumentId
|
||||
version = instrumentVersion
|
||||
description = "Instrument representing units of USD"
|
||||
validAsOf = now
|
||||
observers = empty
|
||||
-- ISSUE_CASH_INSTRUMENT_END
|
||||
|
||||
-- Alice and Bank create a holding directly using the template
|
||||
-- CREATE_ALICE_DIRECT_HOLDING_BEGIN
|
||||
aliceHoldingRequest <- submit alice do
|
||||
createCmd HoldingRequest with
|
||||
instrument = instrumentKey
|
||||
account = aliceAccount
|
||||
amount = 1000.0
|
||||
owner = alice
|
||||
custodian = bank
|
||||
|
||||
aliceHoldingCid <- submit bank do exerciseCmd aliceHoldingRequest Accept
|
||||
-- CREATE_ALICE_DIRECT_HOLDING_END
|
||||
|
||||
-- Alice deposits cash at the bank
|
||||
-- CREATE_ALICE_HOLDING_BEGIN
|
||||
aliceRequestCid <- submit alice do
|
||||
createCmd CreditAccount.Request with
|
||||
account = aliceAccount
|
||||
instrument = instrumentKey
|
||||
amount = 1000.0
|
||||
|
||||
aliceCashHoldingCid <- submit bank do exerciseCmd aliceRequestCid CreditAccount.Accept
|
||||
-- CREATE_ALICE_HOLDING_END
|
||||
|
||||
pure HoldingState with
|
||||
alice
|
||||
bank
|
||||
bob
|
||||
public
|
||||
aliceAccount
|
||||
bobAccount
|
||||
cashInstrument = instrumentKey
|
||||
holdingFactoryCid
|
||||
aliceCashHoldingCid
|
||||
|
||||
-- | Creates a user + party given a hint.
|
||||
createParty : Text -> Script Party
|
||||
createParty name = do
|
||||
party <- allocatePartyWithHint name $ PartyIdHint name
|
||||
userId <- validateUserId name
|
||||
createUser (User userId (Some party)) [CanActAs party]
|
||||
pure party
|
||||
|
||||
-- | Propose / Accept template to create a holding.
|
||||
template HoldingRequest
|
||||
with
|
||||
owner : Party
|
||||
-- ^ Owner of the holding.
|
||||
custodian : Party
|
||||
-- ^ Custodian of the holding.
|
||||
instrument : InstrumentKey
|
||||
-- ^ The instrument of which units are held.
|
||||
account : AccountKey
|
||||
-- ^ The account at which the holding is held. Defines the holding's owner and custodian.
|
||||
amount : Decimal
|
||||
-- ^ Number of units.
|
||||
where
|
||||
signatory owner
|
||||
observer custodian
|
||||
|
||||
choice Accept : ContractId Fungible.Fungible
|
||||
controller custodian
|
||||
do
|
||||
create Fungible.Fungible with
|
||||
instrument
|
||||
account
|
||||
amount
|
||||
lock = None
|
||||
observers = empty
|
@ -112,7 +112,7 @@ runLifecycling = do
|
||||
exerciseCmd lifecycleClaimRuleCid Claim.ClaimEffect with
|
||||
claimer = bob
|
||||
holdingCids = [bobHoldingCid]
|
||||
effectCid
|
||||
effectCid -- This is equivalent to writing effectCid = effectCid
|
||||
batchId = Id "DistributionSettlement"
|
||||
let [bobInstructionCid, bankInstructionCid, couponInstructionCid] = result.instructionCids
|
||||
-- CLAIM_EVENT_END
|
||||
|
@ -96,7 +96,7 @@ runSettlement = do
|
||||
-- ROUTE_PROVIDER_BEGIN
|
||||
routeProviderCid <- toInterfaceContractId @RouteProvider.I <$> submit bank do
|
||||
createCmd SingleCustodian with
|
||||
provider = bank; observers = S.fromList [alice, bob] ; custodian = bank
|
||||
provider = bank; observers = S.fromList [alice, bob]; custodian = bank
|
||||
-- ROUTE_PROVIDER_END
|
||||
|
||||
-- Setup a Settlement Factory facility
|
||||
@ -117,7 +117,7 @@ runSettlement = do
|
||||
payQuantity = qty 1000.0 usdInstrument
|
||||
proposer = bob
|
||||
counterparty = alice
|
||||
routeProviderCid
|
||||
routeProviderCid -- This is equivalent to writing routeProviderCid = routeProviderCid
|
||||
settlementFactoryCid
|
||||
-- DVP_PROPOSE_END
|
||||
|
||||
@ -159,7 +159,7 @@ runSettlement = do
|
||||
actors = singleton bob
|
||||
-- SETTLE_END
|
||||
|
||||
pure $ SettlementState with
|
||||
pure SettlementState with
|
||||
alice
|
||||
bank
|
||||
bob
|
||||
|
@ -1,25 +1,17 @@
|
||||
module Scripts.Transfer where
|
||||
|
||||
import DA.Map (empty, fromList)
|
||||
import DA.Set (singleton)
|
||||
import Daml.Script
|
||||
|
||||
-- INTERFACE DEPENDENCIES --
|
||||
import Daml.Finance.Interface.Account.Factory qualified as Account (F)
|
||||
import Daml.Finance.Interface.Holding.Base qualified as Holding (I)
|
||||
import Daml.Finance.Interface.Holding.Factory qualified as Holding (F)
|
||||
import Daml.Finance.Interface.Instrument.Base.Instrument qualified as Instrument (I)
|
||||
import Daml.Finance.Interface.Types.Common.Types (AccountKey, Id(..), InstrumentKey(..))
|
||||
import Daml.Finance.Interface.Types.Common.Types (AccountKey, InstrumentKey(..))
|
||||
|
||||
-- IMPLEMENTATION DEPENDENCIES --
|
||||
import Daml.Finance.Account.Account qualified as Account (Factory(..))
|
||||
import Daml.Finance.Holding.Fungible qualified as Fungible (Factory(..))
|
||||
import Daml.Finance.Instrument.Token.Instrument (Instrument(..))
|
||||
|
||||
import Workflow.CreateAccount qualified as CreateAccount
|
||||
import Workflow.CreditAccount qualified as CreditAccount
|
||||
import Workflow.Transfer qualified as Transfer
|
||||
|
||||
import Scripts.Holding (HoldingState(..), runHolding)
|
||||
|
||||
-- | Helper container used to transfer state from one script to another.
|
||||
data TransferState = TransferState
|
||||
with
|
||||
@ -34,95 +26,25 @@ data TransferState = TransferState
|
||||
newHoldingCid : ContractId Holding.I
|
||||
deriving (Eq, Show)
|
||||
|
||||
-- | Test script that
|
||||
-- 1. creates an account for Alice and Bob at the Bank
|
||||
-- 2. issues a cash instrument
|
||||
-- 3. credits a cash holding to Alice in her bank account
|
||||
-- 4. transfers the holding from Alice to Bob
|
||||
-- | Test script that transfers a holding from Alice to Bob
|
||||
runTransfer : Script TransferState
|
||||
runTransfer = do
|
||||
|
||||
-- Allocate parties
|
||||
[alice, bank, bob, public] <- mapA createParty $ ["Alice", "Bank", "Bob", "Public"]
|
||||
-- Execute the `runHolding` script. Alice now holds USD 1000 in her account.
|
||||
HoldingState{alice
|
||||
, bank
|
||||
, bob
|
||||
, public
|
||||
, aliceAccount
|
||||
, bobAccount
|
||||
, cashInstrument
|
||||
, holdingFactoryCid
|
||||
, aliceCashHoldingCid} <- runHolding
|
||||
|
||||
-- Account Factory (it is used by the bank to create accounts)
|
||||
-- CREATE_ACCOUNT_FACTORY_BEGIN
|
||||
accountFactoryCid <- toInterfaceContractId @Account.F <$> submit bank do
|
||||
createCmd Account.Factory with provider = bank; observers = empty
|
||||
-- CREATE_ACCOUNT_FACTORY_END
|
||||
|
||||
-- Holding Factory (it is used by the bank to create holdings with the desired implementation)
|
||||
-- CREATE_HOLDING_FACTORY_BEGIN
|
||||
holdingFactoryCid <- toInterfaceContractId @Holding.F <$> submit bank do
|
||||
createCmd Fungible.Factory with
|
||||
provider = bank
|
||||
observers = fromList [("PublicObserver", singleton public )]
|
||||
-- CREATE_HOLDING_FACTORY_END
|
||||
|
||||
-- Alice and Bob setup account @Bank
|
||||
-- SETUP_ALICE_ACCOUNT_BEGIN
|
||||
aliceRequestCid <- submit alice do
|
||||
createCmd CreateAccount.Request with owner = alice; custodian = bank
|
||||
aliceAccount <- submit bank do
|
||||
exerciseCmd aliceRequestCid CreateAccount.Accept with
|
||||
label = "Alice@Bank"
|
||||
description = "Account of Alice at Bank"
|
||||
accountFactoryCid = accountFactoryCid
|
||||
holdingFactoryCid = holdingFactoryCid
|
||||
observers = []
|
||||
-- SETUP_ALICE_ACCOUNT_END
|
||||
|
||||
bobRequestCid <- submit bob do createCmd CreateAccount.Request with owner = bob; custodian = bank
|
||||
bobAccount <- submit bank do
|
||||
exerciseCmd bobRequestCid CreateAccount.Accept with
|
||||
label = "Bob@Bank"
|
||||
description = "Account of Bob at Bank"
|
||||
accountFactoryCid = accountFactoryCid
|
||||
holdingFactoryCid = holdingFactoryCid
|
||||
observers = [alice]
|
||||
|
||||
-- Bank creates the cash instrument
|
||||
-- ISSUE_CASH_INSTRUMENT_BEGIN
|
||||
let
|
||||
instrumentId = Id "USD"
|
||||
instrumentVersion = "0"
|
||||
now <- getTime
|
||||
|
||||
cashInstrumentCid <- toInterfaceContractId @Instrument.I <$> submit bank do
|
||||
createCmd Instrument with
|
||||
depository = bank
|
||||
issuer = bank
|
||||
id = instrumentId
|
||||
version = instrumentVersion
|
||||
description = "Instrument representing units of USD"
|
||||
validAsOf = now
|
||||
observers = empty
|
||||
-- ISSUE_CASH_INSTRUMENT_END
|
||||
|
||||
-- Alice deposits cash at the bank
|
||||
-- CREATE_ALICE_HOLDING_BEGIN
|
||||
aliceRequestCid <- submit alice do
|
||||
createCmd CreditAccount.Request with
|
||||
account = aliceAccount
|
||||
instrument = InstrumentKey with
|
||||
issuer = bank
|
||||
depository = bank
|
||||
id = instrumentId
|
||||
version = instrumentVersion
|
||||
amount = 1000.0
|
||||
|
||||
aliceCashHoldingCid <- submit bank do exerciseCmd aliceRequestCid CreditAccount.Accept
|
||||
-- CREATE_ALICE_HOLDING_END
|
||||
|
||||
-- Bob requests a cash transfer from Alice
|
||||
-- TRANSFER_BEGIN
|
||||
let
|
||||
cashInstrument = InstrumentKey with
|
||||
issuer = bank
|
||||
depository = bank
|
||||
id = instrumentId
|
||||
version = instrumentVersion
|
||||
|
||||
transferRequestCid <- submit bob do
|
||||
createCmd Transfer.Request with
|
||||
receiverAccount = bobAccount
|
||||
@ -134,7 +56,7 @@ runTransfer = do
|
||||
exerciseCmd transferRequestCid Transfer.Accept with holdingCid = aliceCashHoldingCid
|
||||
-- TRANSFER_END
|
||||
|
||||
pure $ TransferState with
|
||||
pure TransferState with
|
||||
alice
|
||||
bank
|
||||
bob
|
||||
@ -144,11 +66,3 @@ runTransfer = do
|
||||
cashInstrument
|
||||
holdingFactoryCid
|
||||
newHoldingCid
|
||||
|
||||
-- | Creates a user + party given a hint
|
||||
createParty : Text -> Script Party
|
||||
createParty name = do
|
||||
party <- allocatePartyWithHint name $ PartyIdHint name
|
||||
userId <- validateUserId name
|
||||
createUser (User userId (Some party)) [CanActAs party]
|
||||
pure party
|
||||
|
@ -38,13 +38,16 @@ template Request
|
||||
controller custodian
|
||||
do
|
||||
let
|
||||
accountKey = AccountKey with
|
||||
custodian -- This is equivalent to writing custodian = custodian
|
||||
owner
|
||||
id = Id label
|
||||
observersSet = S.fromList observers
|
||||
accountKey = AccountKey with custodian = custodian, owner = owner, id = Id label
|
||||
|
||||
accountCid <- exercise accountFactoryCid Account.Create with
|
||||
account = accountKey
|
||||
description = description
|
||||
holdingFactoryCid = holdingFactoryCid
|
||||
description
|
||||
holdingFactoryCid
|
||||
controllers = Account.Controllers with
|
||||
outgoing = S.singleton owner
|
||||
incoming = S.singleton owner
|
||||
|
@ -4,7 +4,7 @@ import DA.Set (fromList, singleton)
|
||||
import Daml.Finance.Interface.Settlement.Batch qualified as Batch (I)
|
||||
import Daml.Finance.Interface.Settlement.Factory qualified as Settlement (F, Instruct(..))
|
||||
import Daml.Finance.Interface.Settlement.Instruction qualified as Instruction (I)
|
||||
import Daml.Finance.Interface.Settlement.RouteProvider qualified as RouteProvider (I, Discover(..))
|
||||
import Daml.Finance.Interface.Settlement.RouteProvider qualified as RouteProvider (Discover(..), I)
|
||||
import Daml.Finance.Interface.Settlement.Types (Step(..))
|
||||
import Daml.Finance.Interface.Types.Common.Types (Id(..), InstrumentQuantity)
|
||||
|
||||
|
@ -3,7 +3,7 @@ module Workflow.Transfer where
|
||||
import DA.Assert ((===))
|
||||
import DA.Set (fromList)
|
||||
import Daml.Finance.Interface.Holding.Base qualified as Holding (I)
|
||||
import Daml.Finance.Interface.Holding.Transferable qualified as Transferable (I, Transfer(..))
|
||||
import Daml.Finance.Interface.Holding.Transferable qualified as Transferable (Transfer(..), I)
|
||||
import Daml.Finance.Interface.Holding.Util (getAmount, getInstrument)
|
||||
import Daml.Finance.Interface.Types.Common.Types (AccountKey(..), InstrumentKey)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user