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.