I also want to point out that listUsers requires admin claims. Do not use this in contexts where you expect to only have claims for an individual user that is not an admin.
Yes that fixed it thanks. I tried something similar with async and await but obviously didn’t get it quite right.
The code works fine on the Canton sandbox where of course by default there is no request authorization. But taking your point about the need for admin claims I guess the use of alias contracts (as at the end of this post) may be a better approach.
My recommendation is to consider auth from the beginning when you build a Daml app. You can ofc use a shared secret or something similar to make up tokens on the fly like create-daml-app does but being explicit about the claims is really important to make sure you can later run your app in an authorized ledger without requiring fundamental redesigns.
As for users, there is another issue if you want to use it as a replacement for alias contracts: The users are local to one participant. So you also wouldn’t be able to distribute your app.
The alias contracts are a good option if you need a mapping of human readable names to party ids that works in an authorized, distributed setting.
React.useEffect can’t take a function that returns a promise. You would need to define the async function from inside the useEffect. You could also extract it (shown in the article above) but below is just a rough example of using async / await
// UserList.tsx
const ledger = userContext.useLedger()
const [users, setUsers] = React.useState<User[] | undefined>(undefined);
React.useEffect( () => {
// defining the async function inside the useEffect
const getUsers = async () => {
try {
const result = await ledger.listUsers();
setUsers(result)
} catch (e) {
return {isOk: false, payload: e}
}
}
// calling the defined function above
getUsers()
}, [])
console.log('users', users)