Nested MapA for Triggers to Exercise a choice

I’m trying to exercise the choice “Invite_New_Asset_Holder” choice on a specific AssetHoldingAccount contract, where the symbol is “ET”

I can get a list of parties, but I’m not sure how to map through that list of parties, and exercise the “Invite_New_Asset_Holder” with the parties as the argument of that choice.

module Trigger where

import Account
import qualified Daml.Trigger as T
import DA.Foldable
import DA.Next.Map (Map)
import DA.Optional (whenSome)
import DA.Action
import qualified DA.List.Total as List

autoSendExampleAssetAccountProposal: T.Trigger ()
autoSendExampleAssetAccountProposal = T.Trigger 
 { initialize = pure (),
  updateState = \_  -> pure (),
  registeredTemplates = T.AllInDar,
  rule = \p -> do
    asset_holding_account_requests <- T.query @Account.AssetHoldingAccountRequest
    let isNotMe = (\requests -> requests.recipient /= p)
    let notMeList = filter (\(_, contract) -> isNotMe contract) asset_holding_account_requests
    let requests = map snd notMeList
    let recipients = map (\r -> r.recipient) requests
    debug recipients
    -- a party can have multiple AssetHoldingAccounts, however I only want to exercise the contract where - 
     --account.assetType.symbol == "ET
    assetAccounts <- T.query @Account.AssetHoldingAccount
    let isET = (\account -> account.assetType.symbol == "ET")
    let etAccounts = filter (\(_, contract) -> isET contract) assetAccounts
    -- the length of this should be one, always
    let cids = map fst etAccounts

     -- Somewhere here, I need to emitCommands I believe, because right now, I can log everything I need to in debug, but the ledger doesn't update with the result from exercising the choice. 

    let doSomething = map(\c -> map(\r -> T.exerciseCmd c Invite_New_Asset_Holder with recipient = r) recipients ) cids
    

    debug $ "TRIGGERED",
  heartbeat = None

}

Any pointers on what I should be doing?

Your doSomething looks like it has type [[Command]], which is a good place to be. You now need to decide how you want to execute those commands. Each emitCommands results in one ledger transaction.

Do you want them all to be executed in one big transaction?

emitCommands (concat doSomething) []

Do you want them to be batched per account?

mapA (\cs -> emitCommands cs []) doSomething

Or do you want to run each command in its own transaction?

mapA (\c -> emitCommands [c] []) (concat doSomething)
2 Likes

Fixed the issue with the looping of the trigger (or perhaps duplicated commands in this case, since it was resolved with some unless and T.dedupExercise

autoSendExampleAssetAccountProposal: T.Trigger ()
autoSendExampleAssetAccountProposal = T.Trigger 
 { initialize = pure (),
  updateState = \_  -> pure (),
  registeredTemplates = T.RegisteredTemplates [T.registeredTemplate @Account.AssetHoldingAccountRequest, T.registeredTemplate @Account.AssetHoldingAccount],
  rule = \p -> do
    asset_holding_account_requests <- T.query @Account.AssetHoldingAccountRequest
    let isNotMe = (\requests -> requests.recipient /= p)
    let notMeList = filter (\(_, contract) -> isNotMe contract) asset_holding_account_requests
    let requests = map fst notMeList


    debug ("requests",requests)
    assetAccounts <- T.query @Account.AssetHoldingAccount
    debug assetAccounts
    let isET = (\account -> account.assetType.symbol == "ET" && account.assetType.issuer == p)
    let etAccounts = filter (\(_, contract) -> isET contract) assetAccounts
    let cids = map fst etAccounts
    
    
    unless ( DA.Foldable.null requests && DA.Foldable.null cids ) do
      let (cid, c) = head etAccounts

      mapA_(\request -> T.dedupExercise request Accept with assetHoldingAccount = cid)  requests
      pure()
    debug $ "TRIGGERED",
  heartbeat = None
}