Delegated Accounts

A core feature of the cryptoasset-wallet package is the ability to work with the Pl^g-based CENNZnet Authorization protocol.

In brief, this protocol allows for keys to delegate authority to other keys under a top-level authority. This system is especially useful for permission management and replication and recovery of lost keys. It’s recommended that developers familiarize themselves with the Authorization protocol (documentation pending).

The wallet and account functionality benefit greatly from this protocol, as it allows the wallet to disover accounts that exist in another instance of a wallet, or another system alltogether. These accounts can then delgate permission to transfer to our wallet.

Events

Much of the delegated accounts system is driven through events. Event listeners should generally be hooked up on app start where required. See the Events documentation for more details.

Linking a Wallet

To enable the Authorization protocol against a wallet, we need to call the wallet.applyDelegatedAuthorizationAgency method on our target instance. The path provided will yield keys corresponding to the root delegatee agent to be used as an authority over all external accounts.

Note

The path provided must be hardened e.g. m/1234'. Not providing a path argument will result in the use of the m/140990' aka birthday path

Enabling the wallet authorization protocol will set the following processes in motion:

Wallet Agent Registration

Firstly, before the wallet instance can be linked to the authorization protocol, we need to ensure the agent is registered as a sibling. This process only needs to happen once, then future instantiations of the wallet will continue with the processes below given the same agent path.

If the agent key derived from the agent path provided in the wallet.applyDelegatedAuthorizationAgency call is not registered, the event stream will yield a walletRegistrationRequired event providing the wallet context and the required registration payload to be used with the auth-agent-sdk package.

Once the registration is complete, wallet.applyDelegatedAuthorizationAgency should be called again with the same path provided.

Local Account Registration

Secondly, once the root wallet agent is registered - every time a new local account is added to the wallet through wallet.addAccount, the events stream will yield an accountRegistrationRequested event indicating that the account can be registered as a sibling to the wallet root delegatee (The path provided in the wallet.applyDelegatedAuthorizationAgency method call)

There is no requirement to register an account, however you may wish to register an account should there be a future need to have access to this account in the context of key recovery or wallet duplication - i.e. having multiple permissioned instances of the same wallet.

Registration also allows all of your other connected applications to be permissioned to use this account as required, therefore is recommended.

Discovering External Accounts

Lastly, when the authorization protocol is linked to the wallet, the package will use the agent provided to discover any external accounts that the wallet may or may not have permission to spend from.

Each account that is automatically added to the wallet will raise an accountAdded event. We recommend handling this event, ensuring that the new account is delegated and adding all the assets your dApp requires.

1
2
3
4
5
6
7
8
 const { events } = require('cryptoasset-wallet')

 events.on('AccountAdded', account => {
     if (account.delegationContext.isDelegated) {
         account.addAsset('CENNZ')
         account.addAsset('SYLO')
     }
 })

In the case that the wallet already has permissions over an external account, the account will be added to the wallet.accounts collection and the account.assets.CENNZ.send method is ready to use.

In the case that the wallet delegatee agent does not yet have permissions over the external account, the account will still be added to the wallet.accounts, however the event stream will yield a supplementary accountPermissionRequested event. This event indicates that the user may wish to request for permissions over this account.

Although permissions are not required to continue using some aspects of the account (fetching balance and transfer history), permission is required to send funds. Attempting to call account.assets.{asset}.send or account.assets.{asset}.approve on an unpermissioned delegated account will cause the transfer to be aborted and an accountPermissionRequired event to be seen on the events stream.

Note

Distinct events: accountPermissionRequestedaccountPermissionRequired

Both of the account permission events provide the account context and the permissions payload that should be requested through the auth-agent-sdk in order to send from the account.