Perform fetch command as a different party than the controller

This is a snippet of my choice:

    postconsuming choice AdminRightsModify : WalletId
      with
        authorisedUser : Party
        public : Party
      controller authorisedUser
      do
         adminWallet   <- fetch @Wallet adminWalletId

Admin Wallet is a public contract that anyone should be able to fetch. Admin wallet has a public party as its observer which should be able to perform this function. However, the controller of the choice is some other party. I am getting an authorisation error when I try to perform this function. Is there any way I can make the public party execute the fetch command instead of the controller of the choice?

On Wallet you can implement your own public fetch:

nonconsuming choice Public_Fetch : Wallet
  with
    fetcher : Party
  controller fetcher
  do return this

Then at the callsite:

postconsuming choice AdminRightsModify : WalletId
      with
        authorisedUser : Party
      controller authorisedUser
      do
         adminWallet   <- exercise adminWalletId with fetcher = authorizedUser

@bernhard, I must be missing something here because I don’t quite see how your solution works. I fail to see what the Public_Fetch choice you suggested could possibly accomplish. To be able to exercise the Public_Fetch choice the controller party must have visibility of the Wallet contract, right? And if this party does have visibility of the Wallet contract, then it can just fetch the contract rather than exercise the Public_Fetch choice on it. In other words the body of the AdminRightsModify choice in your example could use fetch adminWalletId command instead of exercise adminWalletId with fetcher = authorizedUser. The effect would be the same, and in both cases the controller of the AdminRightsModify choice needs to have visibility of the Wallet contract, which takes us back to the original issue @Divyansh_Gupta_ATR10 faced. I for one don’t see how it can be solved without making the controller of the AdminRightsModify choice an observer on the Wallet contract, submitting the command to exercise AdminRightsModify choice from a ledger client with a user with CanReadAs credentials of the public party or using explicit disclosure. Am I missing something?

I added the public party as a controller to my original choice. The modified code snippet is as follows

    postconsuming choice AdminRightsModify : WalletId
      with
        authorisedUser : Party
        public : Party
      controller authorisedUser, public
      do
         adminWallet   <- fetch @Wallet adminWalletId

I am able to exercise this choice with the help of a user that can act as both of these parties. The public party can’t exercise this choice by itself, which prevents any misuse of this authorisation. I created the user as follows:

{
  "userId": "transfer",
  "primaryParty": "transfer::122019adbb9373eefc1cb0194e1fc889b0b7b1cb22d1a4c5f10c9694f5389741b51e",
  "rights": [
    {
      "type": "CanActAs",
      "party": "transfer::122019adbb9373eefc1cb0194e1fc889b0b7b1cb22d1a4c5f10c9694f5389741b51e"
    },
    {
      "type": "CanActAs",
      "party": "public::122019adbb9373eefc1cb0194e1fc889b0b7b1cb22d1a4c5f10c9694f5389741b51e"
    }
  ]
}

Thank you for your help.

1 Like

@Divyansh_Gupta_ATR10, if in the workflow you’re implementing the AdminRightsModify choice is exercised by a command submitted from a ledger client, then your implementation could be slightly simpler. You don’t need to make the public party a controller on the AdminRightsModify choice. You also don’t need to pass the public party as a parameter to this choice. The following will work as long as the user submitting the command to exercise the choice has CanActAs privileges of the authorisedUser party and CanReadAs privileges of the public party.

    postconsuming choice AdminRightsModify : WalletId
      with
        authorisedUser : Party
      controller authorisedUser
      do
         adminWallet   <- fetch @Wallet adminWalletId
1 Like