Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions escrow/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.lib
32 changes: 32 additions & 0 deletions escrow/daml.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
sdk-version: 2.10.2
name: escrow
source: daml
version: 0.0.1
dependencies:
- daml-prim
- daml-script-lts
- daml-stdlib
data-dependencies:
# LUNAR DOLLAR PROJECT
- ../lunar-dollar/.daml/dist/lunar-dollar-1.0.0.dar
# INTERFACE DEPENDENCIES
- .lib/daml-finance-interface-account.dar
- .lib/daml-finance-interface-holding.dar
- .lib/daml-finance-interface-instrument-base.dar
- .lib/daml-finance-interface-instrument-token.dar
- .lib/daml-finance-interface-lifecycle.dar
- .lib/daml-finance-interface-settlement.dar
- .lib/daml-finance-interface-types-common.dar
- .lib/daml-finance-interface-util.dar
# IMPLEMENTATION DEPENDENCIES
- .lib/daml-finance-account.dar
- .lib/daml-finance-holding.dar
- .lib/daml-finance-instrument-token.dar
- .lib/daml-finance-lifecycle.dar
- .lib/daml-finance-settlement.dar
init-script: Scripts.SetupAll:setupAll
build-options:
- --target=1.17
- -Wno-upgrade-interfaces
- -Wno-upgrade-exceptions

68 changes: 68 additions & 0 deletions escrow/daml/Escrow.daml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
module Escrow where

import Daml.Finance.Interface.Holding.V4.Holding qualified as Holding (I)
import Daml.Finance.Interface.Types.Common.V3.Types (AccountKey, InstrumentKey)

import Holding.Transfer (splitAndTransfer)

template EscrowProposal
with
buyer : Party
seller : Party
arbiter : Party
bank : Party
instrumentKey : InstrumentKey
amount : Decimal
buyerAccount : AccountKey
sellerAccount : AccountKey
escrowAccount : AccountKey
description : Text
where
signatory buyer
observer seller, bank, arbiter

ensure amount > 0.0

choice Accept : ContractId Escrow
with
holdingCid : ContractId Holding.I
controller seller, bank
do
escrowHoldingCid <- splitAndTransfer [buyer, bank] escrowAccount amount holdingCid
create Escrow with
buyer
seller
arbiter
bank
instrumentKey
amount
sellerAccount
escrowAccount
escrowHoldingCid
description

choice Cancel : ()
controller buyer
do pure ()

template Escrow
with
buyer : Party
seller : Party
arbiter : Party
bank : Party
instrumentKey : InstrumentKey
amount : Decimal
sellerAccount : AccountKey
escrowAccount : AccountKey
escrowHoldingCid : ContractId Holding.I
description : Text
where
signatory buyer, seller
observer bank, arbiter

choice Release : ContractId Holding.I
controller buyer, bank
do
splitAndTransfer [bank, seller] sellerAccount amount escrowHoldingCid

79 changes: 79 additions & 0 deletions escrow/daml/Scripts/Escrow.daml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
module Scripts.Escrow where

import Daml.Script

import Daml.Finance.Interface.Holding.V4.Holding qualified as Holding (I)
import Daml.Finance.Interface.Types.Common.V3.Types (AccountKey(..), Id(..))

import Escrow (EscrowProposal(..), Escrow, Accept(..), Release(..))
import Scripts.Util (lookupParty, getLNRD)

data CreateEscrowProposalArgs = CreateEscrowProposalArgs with
buyer : Text
seller : Text
arbiter : Text
amount : Decimal
description : Text

createEscrowProposal : CreateEscrowProposalArgs -> Script (ContractId EscrowProposal)
createEscrowProposal args = do
buyer <- lookupParty args.buyer
seller <- lookupParty args.seller
arbiter <- lookupParty args.arbiter
bank <- lookupParty "Bank"
(_, lnrd) <- getLNRD

let
buyerAccount = AccountKey with custodian = bank; owner = buyer; id = Id (args.buyer <> "'s Account")
sellerAccount = AccountKey with custodian = bank; owner = seller; id = Id (args.seller <> "'s Account")
escrowAccount = AccountKey with custodian = bank; owner = bank; id = Id "Escrow Account"

proposalCid <- submit buyer do
createCmd EscrowProposal with
buyer
seller
arbiter
bank
instrumentKey = lnrd.instrumentKey
amount = args.amount
buyerAccount
sellerAccount
escrowAccount
description = args.description

debug $ "Created escrow proposal for " <> show args.amount <> " LNRD"
pure proposalCid

data AcceptEscrowArgs = AcceptEscrowArgs with
buyer : Text
seller : Text
proposalCid : ContractId EscrowProposal
holdingCid : ContractId Holding.I

acceptEscrow : AcceptEscrowArgs -> Script (ContractId Escrow)
acceptEscrow args = do
seller <- lookupParty args.seller
bank <- lookupParty "Bank"

escrowCid <- submitMulti [seller, bank] [] do
exerciseCmd args.proposalCid Accept with
holdingCid = args.holdingCid

debug "Escrow funded"
pure escrowCid

data ReleaseEscrowArgs = ReleaseEscrowArgs with
buyer : Text
escrowCid : ContractId Escrow

releaseEscrow : ReleaseEscrowArgs -> Script (ContractId Holding.I)
releaseEscrow args = do
buyer <- lookupParty args.buyer
bank <- lookupParty "Bank"

holdingCid <- submitMulti [buyer, bank] [] do
exerciseCmd args.escrowCid Release

debug "Escrow released to seller"
pure holdingCid

22 changes: 22 additions & 0 deletions escrow/daml/Scripts/Setup.daml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module Scripts.Setup where

import Daml.Script

import Daml.Finance.Interface.Account.V4.Factory qualified as AccountFactory (I)
import Daml.Finance.Interface.Types.Common.V3.Types (AccountKey, HoldingFactoryKey(..), Id(..))

import Scripts.Util (lookupParty, createBankAccount)

setupEscrow : Script AccountKey
setupEscrow = do
bank <- lookupParty "Bank"
alice <- lookupParty "Alice"
bob <- lookupParty "Bob"

[(accountFactoryCid, _)] <- queryInterface @AccountFactory.I bank
let holdingFactory = HoldingFactoryKey with provider = bank; id = Id "Holding Factory"

escrowAccount <- createBankAccount bank holdingFactory accountFactoryCid bank "Escrow Account" [alice, bob]
debug "Created bank escrow account"
pure escrowAccount

14 changes: 14 additions & 0 deletions escrow/daml/Scripts/SetupAll.daml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module Scripts.SetupAll where

import Daml.Script

import Daml.Finance.Interface.Types.Common.V3.Types (AccountKey)

import LunarDollar.Setup (setupLunarDollar)
import Scripts.Setup (setupEscrow)

setupAll : Script AccountKey
setupAll = do
setupLunarDollar
setupEscrow

94 changes: 94 additions & 0 deletions escrow/daml/Tests/EscrowTest.daml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
module Tests.EscrowTest where

import Daml.Script

import Scripts.SetupAll (setupAll)
import Scripts.Mint (MintArgs(..), mint)
import Scripts.Balance (BalanceArgs(..), balance)
import Scripts.Escrow
( CreateEscrowProposalArgs(..), createEscrowProposal
, AcceptEscrowArgs(..), acceptEscrow
, ReleaseEscrowArgs(..), releaseEscrow
)

testEscrowHappyPath : Script ()
testEscrowHappyPath = do
_ <- setupAll

debug "=== Escrow Happy Path Test ==="

holdingCid <- mint MintArgs with
recipient = "Alice"
amount = 50.0

debug "1. Alice has 50 LNRD"
balance BalanceArgs with party = "Alice"

proposalCid <- createEscrowProposal CreateEscrowProposalArgs with
buyer = "Alice"
seller = "Bob"
arbiter = "Bank"
amount = 50.0
description = "Test escrow"

debug "2. Alice created escrow proposal for 50 LNRD"

escrowCid <- acceptEscrow AcceptEscrowArgs with
buyer = "Alice"
seller = "Bob"
proposalCid
holdingCid

debug "3. Escrow funded — LNRD locked in escrow account"
balance BalanceArgs with party = "Alice"

_ <- releaseEscrow ReleaseEscrowArgs with
buyer = "Alice"
escrowCid

debug "4. Buyer released — LNRD transferred to seller"
balance BalanceArgs with party = "Alice"
balance BalanceArgs with party = "Bob"

pure ()

testEscrowWithSplit : Script ()
testEscrowWithSplit = do
_ <- setupAll

debug "=== Escrow With Split Test ==="

holdingCid <- mint MintArgs with
recipient = "Alice"
amount = 200.0

debug "1. Alice has 200 LNRD"

proposalCid <- createEscrowProposal CreateEscrowProposalArgs with
buyer = "Alice"
seller = "Bob"
arbiter = "Bank"
amount = 75.0
description = "Partial escrow"

debug "2. Alice created escrow proposal for 75 LNRD"

escrowCid <- acceptEscrow AcceptEscrowArgs with
buyer = "Alice"
seller = "Bob"
proposalCid
holdingCid

debug "3. Escrow funded — 75 LNRD locked, 125 LNRD remains with Alice"
balance BalanceArgs with party = "Alice"

_ <- releaseEscrow ReleaseEscrowArgs with
buyer = "Alice"
escrowCid

debug "4. Released — Alice: 125 LNRD, Bob: 75 LNRD"
balance BalanceArgs with party = "Alice"
balance BalanceArgs with party = "Bob"

pure ()

29 changes: 29 additions & 0 deletions escrow/get-dependencies.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

set -euo pipefail

# Create .lib directory
if [[ -d .lib ]]; then
rm -r .lib
fi
mkdir .lib

# Get the dependency list
echo "Downloading the list of dependencies"
version="0.0.6"
curl -L# \
-H 'Cache-Control: no-cache, no-store' \
-o .lib/${version}.conf \
https://raw.githubusercontent.com/digital-asset/daml-finance/main/docs/code-samples/tutorials-config/${version}.conf

# For each dependency, download and install
while IFS=" " read -r url out
do
printf "Downloading: %s, to: %s\n" "$url" "$out"
curl -Lf# "${url}" -o ${out}
done < .lib/${version}.conf

echo "All dependencies successfully downloaded!"

6 changes: 6 additions & 0 deletions get-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ echo ">>> vault"
cd "$SCRIPT_DIR/vault"
./get-dependencies.sh

# Escrow
echo ""
echo ">>> escrow"
cd "$SCRIPT_DIR/escrow"
./get-dependencies.sh

echo ""
echo "========================================"
echo "All dependencies downloaded successfully!"
Expand Down
3 changes: 1 addition & 2 deletions lunar-dollar/daml/Scripts/Setup.daml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ import DA.Map qualified as Map (fromList)
import DA.Set qualified as Set (fromList, empty)

import Daml.Finance.Interface.Account.V4.Factory qualified as AccountFactory (I)
import Daml.Finance.Interface.Types.Common.V3.Types (AccountKey(..))
import Daml.Finance.Interface.Types.Common.V3.Types (AccountKey(..), Id(..), HoldingStandard(..), InstrumentKey(..))

import LunarDollar (LunarDollar(..))
import LunarDollar qualified
import Daml.Finance.Interface.Instrument.Token.V4.Factory qualified as TokenFactory (Create(..), I)
import Daml.Finance.Interface.Instrument.Token.V4.Types (Token(..))
import Daml.Finance.Interface.Types.Common.V3.Types (Id(..), HoldingStandard(..), InstrumentKey(..))

import Daml.Finance.Account.V4.Account qualified as Account (Factory(..))
import Daml.Finance.Holding.V4.Factory qualified as Holding (Factory(..))
Expand Down
1 change: 1 addition & 0 deletions multi-package.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
packages:
- ./vault
- ./lunar-dollar
- ./escrow