From discussions with @Quazia and @Paty, amongst others.
If youâd like, you can skip to the initial API mock below (see âPath forwardâ).
Preamble
Terminology
- Immediate forwarders: those that automatically forward their actions, pending immediate checks (e.g. the Token Manager immediately executes actions if the sender holds the associated token)
- Interactive forwarders: those that require interaction for an action to pass (e.g. the Voting app only executes actions if the associated vote passes)
Another way to categorize these two types is to use timing terminology:
- Immediate forwarders are synchronous
- Interactive forwarders are asynchronous.
Status quo in the Aragon client
Users lack any in-app feedback regarding forwarded actions.
They go to an app, decide on an action, and sign a transaction (containing that actionâs intent) that eventually gets mined. Afterwards theyâre left in the dark, because theyâve received no feedback about what happened after and if they need to do anything (unless the intent was synchronously successful, e.g. the sender was the only possible voter in the entire organization).
Although their original action intent is encoded in the transaction they signed, this intent may require any number of prior steps before it can finally be executed on the âtargetâ app (e.g. Token Manager -> Voting -> Finance).
For clarity, letâs step through an example flow using a 2-of-2 multisig organization* on the current 0.6 client:
- I go to the Finance app, and want to transfer out 100 DAI for an Aragon hoodie (the action intent)
- I enter the required details in the âWithdrawâ panel
- The signing panel opens, informing me of the steps my action intent will take
- I sign the transaction
- âŚ
- Wait; browse some other Aragon merch to keep busy
- Some time afterwards, my signing provider tells me my transaction was mined
- But nothingâs changed in the UI! Whut am I gonna dooo??
- âŚ
- Realize the Token Manager is the address I sent the transaction to (as it was the initial forward), so I go to its UI
- Ainât nothing here about my DAI transfer!
- âŚ
- Remember the signing panel told me it would go through the Voting app afterwards, so I go to its UI
- See my transfer intent in a vote
- Vote âyesâ
- Bug other multisig owner to vote yes
- âŚ
- If the other multisig owner votes yes, the transfer is complete and shows up in the Finance appâs UI
* Note: the default permissions of a 2-of-2 multisig organization require all actions to pass through a vote, and only token holders can create votes
Problem Areas
Any action not directly executed against an appâs contract (which will be almost all actions in a typical organization) is untraceable for the user, unless they have strong knowledge of how the organization is set up and what each appâs UI is meant to show.
There is no immediate feedback in the final (âtargetâ) appâs UI when you invoke an action that requires an interactive forwarder.
The upcoming transactions activity panel in 0.7 will show which app youâve sent a transaction to, but for default organizations this will almost always be the Token Manager because itâs the initial forwarder (for the token holder check).
Technical excuses for poor UX
Getting the required on-chain information to ascertain the status of any particular action is time and resource intensive if we do it naively.
Technically, with a built-in DB or intermediate caching layer, we could process all Ethereum blocks, scan all transactions, and build up a model of the organization where we knew everything about it.
Realistically, this is impossible to do in a way to that would be usable for users. Our client would feel like Augurâs, where itâd take days to initially sync. In the future more intermediate caching layers will be necessary, but until then, weâre trying to sync as much as we can off of the chain directly.
Path forward
We can help the client understand more about an organization and its appsâ pending actions by providing API hooks. On some level, the idea is to âcheatâ the information barrier by asking apps to provide the relevant information.
App API
Apps will need an API (in aragonAPI) to both receive and send information about pending actions. However, the âsenderâ side API is only intended to be used by forwarders.
Sender API
Used by forwardersâapps implementing the IForwarder
interface.
On receiving a pending action (most likely an EVMScript), send information back to the Aragon client with:
- An ID (e.g.
voteId
) - The âtargetâ action, including address and calldata (would require decoding and unwrapping EVMScripts)
- (Perhaps optional) The execution path left (would require decoding and unwrapping EVMScripts)
The Aragon client could then take this information, register it based on the app that sent it, and notify the âtargetâ app (by using the address) about the pending action.
The ID is important to allow the forwarder to âderegisterâ pending actions once its been executed, to allow the âtargetâ app to stop showing the pending action (either it will appear directly in the âtargetâ appâs UI, or itâs the next forwarderâs responsibility to register the action again).
Note: This is primarily intended to be used by interactive forwarders, as I find it pointless for immediate forwarders. However, you could still use it in immediate forwarders, and could receive this information in the frontend by emitting an event in the forward()
function.
Receiver API
Most apps should use this.
A simple observable API that emits an array of pending actions and where they were registered from. Apps shouldnât be too confident about these actions actually executing, as they may never reach their final target (e.g. failed votes).
In the example flow above, this would allow the Finance app to immediately display a âTransferâ pending action in its UI after the transaction was mined, as well as where it was stuck at the moment (Voting). The calldata could be parsed to know the function call and render more useful information to a user.
Note: this will likely be accompanied by a recommended UX pattern implemented in each of the default Aragon apps (Finance, Token Manager, Voting).
Metadata declaration
It may also help the Aragon client render information if apps declared what type of forwarding interface they expect. In particular, it is more important for the client to know (and therefore help users with) interactive forwarders than immediate forwarders.
We could add a simple flag to an appâs arapp.json
for advertising its forwarding type.
Notes
This API pushes the implementation responsibility to individual forwarding apps. Apps that donât correctly implement these APIs would effectively behave similarly to today, where pending actions become âlostâ.