Skip to content

Conversation

@PetromirDev
Copy link
Member

@PetromirDev PetromirDev commented Nov 21, 2025

How it used to work:

In the portfolio and defi positions controllers:

  1. The portfolio is updated via the portfolio controller. For every network: call to Velcro for hints → Deployless → call to Cena for asset prices.
  2. DeFi positions are updated separately via the DeFi positions controller. `A single call to Cena for all DeFi positions (using Debank) | IN PARALLEL WITH | Deployless calls for every network to fetch custom DeFi positions.
  3. Each controller updates its own state at the end of each update.`

In the selected account controller

In the meantime, the selectedAccount controller listens for updates from both controllers. Its job is to combine the state from DeFi and the portfolio, which is a tedious task because:

  • The portfolio and DeFi don’t load at the same time.
  • Internal networks don’t have DeFi positions.
  • The selected account lib had to calculate the total value for every network, the total value of the DeFi positions, and then combine the results. In addition, it had to calculate the token array by looping through the assets from the DeFi positions and the assets from the portfolio.

The biggest problem in the described flow is that this logic has to be executed on every controller update. This turned out to be expensive for large accounts, which led us to implement caching.

How caching works:

  1. Store the combined results for each network, together with identifying information for the update (user nonce, update timestamps, account ops, etc.).
  2. Compare the cached results with the current identifying information and determine whether the state has to be recalculated.
  3. Recalculate and update the cache.

This was needed because every network update resulted in a recalculation of the entire state. Imagine a user with 12 networks, where each network emits once in both controllers, resulting in 24 recalculations of the state.

How it works now:

  • The DeFi positions controller is deleted and replaced with a library.
  • DeFi positions are now part of the portfolio state (similar to tokens and collections).
  • The call to Velcro is moved to the portfolio controller (it was previously in the lib).
  • The call to Velcro returns the DeFi positions together with the hints.
  • We call the new Velcro route before the portfolio lib is called, to fetch the hints and DeFi positions.
  • The hints and positions are passed to the portfolio lib so it can attach flags to tokens, remove their price if needed, and discover tokens.
  • We call the portfolio lib together with the custom positions fetch call.
  • After both return results, we merge the Debank and custom positions, as well as the portfolio and DeFi states. (inside of the portfolio controller, once per network and not on every emit update)
  • The selected account controller simply combines all tokens, collections, DeFi positions, and total balances (using simple spread and addition operations).
  • All selectedAccount controller caching logic is removed.

Closes https://github.com/AmbireTech/ambire-app/issues/3971
Closes https://github.com/AmbireTech/ambire-app/issues/5842

@PetromirDev PetromirDev marked this pull request as ready for review December 1, 2025 09:13
@jordan-enev
Copy link
Member

jordan-enev commented Jan 18, 2026

Batched 2 txns on Base with the first accounts, open the dashboard banner, but a pending to be signed transaction from other accounts is being show. We have to check if this is an issue with this PR or already existing ones.

2026-01-18.13-10-44.mp4

@PetromirDev PetromirDev merged commit e28ab0e into v2 Jan 22, 2026
2 of 3 checks passed
@superKalo superKalo mentioned this pull request Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants