Help Needed with Daml Trigger (Syntax related)

Currently, the below trigger exercises the choice “AssetHoldingAccountProposal_Accept” for all incoming AssetHoldingAccountProposals. Upon accepting, the proposal gets archived, and the outstanding proposal contracts become a count of 0, and the trigger stops firing.

ISSUE:
The issue is that, there will be the situation where the AssetHoldingAccountProposal CANNOT be accepted, becaues the user already has an existing AssetHoldingAccount.

WHAT I WANT TO DO:

  • For incoming AssetHoldingAccountProposals, query the AssetHoldingAccount by key,
  • if the result is not null (meaning there exists an assetHoldingAccount for this corresponding proposal)
  • Reject the proposal (proposal gets archived)
  • if null, accept the proposal (proposal gets archived)

This will stop the trigger from firing endlessly if I’m sending a proposal to someone that already has the account.

AssetHoldingAccountProposal Template

template AssetHoldingAccountProposal with
    account : AssetHoldingAccount
    recipient : Party
  where
    signatory account.assetType.issuer
    observer recipient

    choice AssetHoldingAccountProposal_Accept : ContractId AssetHoldingAccount
      controller recipient 
      do
        create account with
          owner = recipient

    choice AssetHoldingAccountProposal_Reject : ()
      controller recipient 
      do
        return ()

CURRENT TRIGGER, (does not query AssetHoldingAccount)

module AcceptAssetInviteTrigger where

import Account
import qualified Daml.Trigger as T
import DA.Foldable
import DA.Action

-- Auto accept assset invitation
acceptAssetInviteTrigger: T.Trigger ()
acceptAssetInviteTrigger = T.Trigger 
 { initialize = pure (),
  updateState = \_  -> pure (),
  registeredTemplates = T.RegisteredTemplates [T.registeredTemplate @AssetHoldingAccountProposal],
  rule = \p -> do
    requests <- T.query @AssetHoldingAccountProposal
    let isMe = (\requests -> requests.recipient == p)
    let meList = filter (\(_, contract) -> isMe contract) requests
    let requests = map fst meList

    debug ("asset holding account invites", requests)

    
    unless ( DA.Foldable.null requests ) do
       mapA_ (\request ->  T.dedupExercise request AssetHoldingAccountProposal_Accept) requests
      
    debug $ "TRIGGERED",
  heartbeat = None
}

I’m trying to do something like the below

module AcceptAssetInviteTrigger where

import Account
import qualified Daml.Trigger as T
import DA.Foldable
import DA.Action
import DA.Optional (isSome, whenSome)

-- Auto accept assset invitation
acceptAssetInviteTrigger: T.Trigger ()
acceptAssetInviteTrigger = T.Trigger 
 { initialize = pure (),
  updateState = \_  -> pure (),
  registeredTemplates = T.RegisteredTemplates [T.registeredTemplate @AssetHoldingAccountProposal, T.registeredTemplate @AssetHoldingAccount],
  rule = \p -> do
    requests <- T.query @AssetHoldingAccountProposal
    let isMe = (\requests -> requests.recipient == p)
    let meList = filter (\(_, contract) -> isMe contract) requests
    let requests =  meList

    debug ("asset holding account invites", requests)

    
    unless ( DA.Foldable.null requests ) do
      case requests of 
        [] -> pure()
        (requestCid, c) :: _ -> do
          optAccount <- T.queryContractKey @AssetHoldingAccount (c.account.assetType, c.account.owner)
          if isSome(optAccount) 
            then do 
              T.dedupExercise requestCid AssetHoldingAccountCloseProposal_Reject
          else do 
            T.dedupExercise requestCid AssetHoldingAccountProposal_Accept
      
    debug $ "TRIGGERED",
  heartbeat = None
}

and I get a red squiggle under the first T.dedupExercise, right below the then do line. Saying

• No instance for (HasExercise
AssetHoldingAccountProposal
AssetHoldingAccountCloseProposal_Reject
r0)
arising from a use of ‘T.dedupExercise’

I’m not sure what the right syntax to use is, I need to map through the incoming requests,
Then query the @AssetHoldingAccount, and then if its NOT null, I need to reject the proposal requests.

It looks like you typoed your choice name. Your trigger is calling AssetHoldingAccountCloseProposal_Reject but the choice is called AssetHoldingAccountProposal_Reject without the Close.

1 Like

… And that fixed it. Thank you!

1 Like