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)
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
}