Multiparty Agreement Combining Sign and Finalize Choices
I am researching the example around multi-party agreement
Multiple party agreement — DAML SDK 1.7.0 documentation
I was wondering if there is a way to combine the Sign and Finalize Choices below into 1 Choice.
The rational for this is that in this case no other logic would need to reside on when to call the “Sign Choice” versus the “Finalize Choice” in any connecting originating systems.
choice Sign : ContractId Pending with
signer : Party
controller signer
do
-- Check the controller is in the toSign list, and if they are, sign the Pending contract
assert (signer `elem` toSign)
create this with alreadySigned = signer :: alreadySigned
choice Finalize : ContractId Agreement with
signer : Party
controller signer
do
-- Check that all the required signatories have signed Pending
assert (sort alreadySigned == sort finalContract.signatories)
create finalContract
An alternative way would be to write a trigger, but wondered if there is maybe a way to accomplish this just inside DAML
Any thoughts ?
Hi there,
You can check each time in the Sign choice whether or not you’re finished. For example:
choice Sign: Either (ContractId Pending) (ContractId Agreement)
with
signer: Party
controller signer
do
assert $ signer `elem` toSign
let
newAlreadySigned = dedup $ signer :: alreadySigned
if (sort newAlreadySigned) == (sort toSign)
then Right <$> create FinalContract with signatories = newAlreadySigned; ..
else Left <$> create this with alreadySigned = newAlreadySigned
Also worth noting is that this approach, while possible, has a few negative side effects:
- Complicates the business logic by having 2 separate concerns in one choice, which also makes this code less flexible
- Complicates they frontend by having to handle one call that returns two different types
I would recommend keeping the choices separate and maybe having the frontend specially handle when they’re the last signer by automatically exercising the finalizing choice.