Module Flows

Module instantiation and execution is a process that is somewhat hidden from the end-user and developer. This section aims to elaborate on the message execution flows for these actions.

Installing and Uninstalling Modules

The following are sequence diagrams of the process of installing and uninstalling a module on an Abstract Account. As you can see, the process happens via the Account, and it can be done by the Account owner through the web-app.

RegistryModule FactoryAccountRegistryModule FactoryAccountalt[adapter][app /standalone]OwnerInstallModule1InstallModule2Query Module Details3Return address4Return code_id5Instantiate module6Register module address7Update module allowlist8Owner
Installing a Module

At this point you should be able to understand the message flow depicted above. Just to be sure, we’ll briefly outline the process’s steps.

Installing a module starts by the Owner of the Account requesting the installation of the module. The request contains the module ID(s) and possible instantiate messages for any App/Standalone modules that should be installed (aka instantiated).

The Account contract verifies the request and forwards it to the Module Factory. The Module Factory then queries the Registry (the on-chain module registry) for the module details. These module details contain both the version of the module as well as its type-specific data. This type-specific data is depicted by the two alternatives (alt) of the returned query.

Either the query returns an Adapter’s address (which is already instantiated) or it returns an App/Standalone code-id. This code-id is then used by the Module Factory to instantiate an instance of that module.

After instantiating the modules, the Account registers the modules internally and updates its whitelist. This whitelisting provides the modules with the ability to proxy message execution through the Account.

AccountAccountOwnerUninstallModule1Deregister module2Update Account Whitelist3Owner
Uninstalling a Module

Uninstalling a Module follows a similar execution flow as shown above.

Info

In both flows we omitted the dependency-check logic, which will be discussed in more detail later.

Example Execution Flows

The following are sequence diagrams of the process of executing a function on a module of an Abstract Account. We show three examples of executing a module: Owner Execution, Adapter Execution, and Dependency Execution.

Let’s explore each of them.

Owner Execution

To execute a (permissioned) message on a specific module, the Owner can call the module directly. The Module knows who the Owner of the Account is.

Module ("addr123")Module ("addr123")OwnerExecute1Owner

Adapter Execution

In the following example, the abstract:dex adapter is installed on an Account, and the Owner requests a swap on a dex. By providing the address of the Account in the call, the adapter can assert that the caller is the Owner of the Account.

Dex PoolAccountRegistryabstract:dexDex PoolAccountRegistryabstract:dexDex::Swap {account: "juno1xd..."}DexMsgDexMsgOwnerCall module1Load address for Account2Address3Resolve asset names4Asset infos5Resolve dex pool6Pool metadata7Build swap msg for target dex8Forward execution9Execute10Owner

Dependency Execution

In this example, we use the Equilibrium App’s Rebalance function as an example. Modules with dependencies (equilibrium:balancer is dependent on abstract:etf and abstract:dex) have their addresses dynamically resolved when called.

Target Dexabstract:dexAccountequilibrium:balancerTarget Dexabstract:dexAccountequilibrium:balancerDexMsgDexMsgUserRebalance1Query Allocations2Allocations3Calculate rebalancing requirements4Query abstract:dex address5Address6Call SwapRouter on dex7Build swap msg for target dex8Load account address9Forward execution10Execute11User

s