Allocate Party if it doesn't exists

I am trying to create a Daml Script that creates Users and Parties on the ledger.

createUsersAndParties = script do
  let 
    userParties = [
      ("alice", "Alice"),
      ("bob", "Bob")]
  forA_ userParties $ uncurry allocatePartyAndCreateUser
  users <- listAllUsers
  return (users)

allocatePartyAndCreateUser userId partyId = script do 
  allocatePartyWithHint partyId (PartyIdHint partyId)
  userIdValidated <- validateUserId userId
  createUser (User userIdValidated (Some party)) [CanActAs party]
  return()

This script could potentially be run more than once, so I would like the script on the second run to just list all the users. When I change the code to the following:

createUsersAndParties = script do
  let 
    userParties = [
      ("alice", "Alice"),
      ("bob", "Bob")]
  forA_ userParties $ uncurry allocatePartyAndCreateUser
  forA_ userParties $ uncurry allocatePartyAndCreateUser
  users <- listAllUsers
  return (users)

I get the error:

Script execution failed:
  Tried to allocate a party that already exists:  Alice

Is there a way to add a try catch in the allocatePartyAndCreateUser function? I have tried using GeneralError as the catch argument but that did not work?

I usually do this by checking if the user exists first. You can find an example of that in create-daml-app.

1 Like

I am pasting this code snippet here for future searches that land on this page.

import DA.Text as T
getOrCreateUserParty : Text -> Script Party
getOrCreateUserParty alias = do
  userId <- validateUserId (T.asciiToLower alias)
  try do
    User _ (Some party) <- getUser userId
    pure party
  catch
    UserNotFound _ -> do
      p <- allocatePartyWithHint alias (PartyIdHint alias)
      createUser (User userId (Some p)) [CanActAs p]
      pure p

I have found it sufficient for demo, test, and educational scripts.

If you use the above, then pressing r in the daml start terminal will not result in a Command allocateParty failed: INVALID_ARGUMENT: INVALID_ARGUMENT... Party already exists: party ... is already allocated on this node

1 Like