I have a contract I would like to make visible to all participants.
template Registration
with
admin: Party
public: Party
where
signatory admin
observer public
I have created a public
party on all participants using a previous post, and I added the readAs
right to all the parties that need to see this contract.
When using the navigator, those parties cannot see this contract:
users.ledger_api.acs.of_party(myUser)
res9: Seq[com.digitalasset.canton.admin.api.client.commands.LedgerApiTypeWrappers.WrappedCreatedEvent] = List()
@ users.ledger_api.users.rights.list("myUser")
res10: UserRights = UserRights(
actAs = Set(
"collector1::12209ef651220a793b7f0abb80ec8667af95da3dc54629e934c8f3e588916a47877a"
),
readAs = Set(
"public::12209ef651220a793b7f0abb80ec8667af95da3dc54629e934c8f3e588916a47877a"
),
participantAdmin = false
)
I have two questions:
- Is it possible to observe this public contract without adding every party as an observer ?
- If this is possible, what should add to my code / user creation, to make this contract visible ?
Thanks
Your code seems perfectly fine here. The issue in in Navigator. The problem is that it only shows you contracts visible to the primary party of your user even if your user has readAs
claims for other parties, see Navigator user login does not reflect the correct access - #2 by cocreature for more details.
That limitation doesn’t apply if you read, e.g., via the JSON API. That’s what create-daml-app does.
3 Likes
thanks for you answer.
I have a similar issue in my test scripts.
test_create_expert = script do
ledgerParties <- allocateParties
-- for debugging
expertId <- validateUserId $ toUserId "Expert"
rights <- listUserRights expertId
debug rights
registrationCid <- createExpert ledgerParties.admin ledgerParties.public ledgerParties.expert
pure()
But I m getting a right error:
Script execution failed on commit at Test.Common:12:30:
Attempt to fetch or exercise a contract not visible to the reading parties.
Contract: #0:0 (Registration:Registration)
actAs: 'Expert'
readAs:
Disclosed to: 'Bank', 'Public'
Trace:
[CanActAs 'Expert',CanReadAs 'Public']
The user Expert is created with CanReadAs = Public
right and the contract is visible to Public.
I don’t understand what’s missing. Can you help me ?
Thanks
How is createExpert
defined?
createExpert: Party -> Party -> Party -> Script (ContractId ExpertAccount)
createExpert admin public expert = do
registrationCid <- submit admin $ createCmd (Registration admin public)
expertAccountRequestCid <- submit expert $ exerciseCmd registrationCid SubmitExpertAccountRequest with ..
submit admin $ exerciseCmd expertAccountRequestCid $ AcceptExpertAccount
With a simpler code where I only do a fetch, it fails too
createExpert admin public expert = do
registrationCid <- submit admin $ createCmd (Registration admin public)
Some t <- queryContractId public registrationCid
debug t
result <- queryContractId expert registrationCid
debug result
I m getting the following logs
Registration {admin = 'Admin', public = 'Public'}
None
I m using the code provided in create-daml-app to create users with public read access.
getOrCreateUser alias publicM = do
userId <- validateUserId $ toUserId alias
try
getUser userId
catch
UserNotFound _ -> do
p <- allocateParty alias
let u = User userId (Some p)
createUser u $ CanActAs p :: [CanReadAs public | Some public <- [publicM]]
pure u
I think you might have gotten confused by the distinction between users and parties and their relation to each other.
Each party can only ever see contracts that are visible to it. So queryContractId expert …
is never going to show contracts expert
is not a stakeholder on.
Users build on top of that: Each user has the right to act/read as some parties. This is particularly useful when working with ledgers that require authorization: You give someone a token that allows them to act as a user and you can then dynamically change which parties that user is authorized to act as. However, each request is still scoped to a set of parties not a set of users. The participant then checks that your user has the right to act/read as those parties.
So in your example you need to use submitMulti [expert] [public]
and queryContractId public
to get contracts visible to public
.
1 Like
@Meriam_Lachkar,
As an alternative to submitMulti [expert] [public]
you can use submitUser expertId
. submitUser
is arguably preferable in test scripts for client app workflows centered around users rather than parties, as it allows to test whether user rights have been assigned correctly.
@cocreature,
Since the client app workflows in Daml 2+ are likely to be centered around users rather than parties, do you think it would be possible and useful to introduce into Daml Script queryUser
, queryFilterUser
, queryContractIdUser
and queryContractKeyUser
by analogy with submitUser
?
3 Likes