← Projects

Building one portfolio view for all my crypto wallets

Why I built Satzo's portfolio view to combine every wallet and DeFi position into one total, and why I replaced daily snapshots with transaction replay.

My crypto is spread across several wallets on different chains. Some of it sits as plain token balances. Some of it is lent out or providing liquidity in DeFi protocols. Looking at one wallet at a time never answered the question I cared about: how much do I have in total?

I wanted one place to see all of it. That became the portfolio view in Satzo, the crypto app I'm building.

What I built

The portfolio page combines every active wallet you've added into one total. Wallets are added by address, and Satzo reads balances from Bitcoin, Solana, Ethereum and the other EVM networks it supports.

The total includes DeFi positions as well as token balances. Right now Satzo scans for:

  • Aave v3 lending and borrowing
  • Pendle positions
  • Morpho collateral and borrows
  • concentrated liquidity on Uniswap v3 and Aerodrome Slipstream

Satzo portfolio view showing one combined total across two demo wallets, pooled holdings, the wallet list, and Aave V3, Pendle and Morpho Blue positions. All figures are demo data.

Borrowed amounts count against the total, so the number is closer to net worth than to a sum of deposits. Protocols that don't have their own display yet go into an "Other DeFi" line, so the total isn't understated just because I haven't built a proper view for them.

One detail matters here. Some DeFi positions show up as receipt tokens in the wallet, like the aTokens you get for supplying to Aave. If I counted those as ordinary balances and also counted the Aave position, the same money would appear twice. Satzo recognises known receipt tokens by contract address and counts them once.

Total first, wallets underneath

I did consider making the wallet list the starting point. I went the other way. The first thing you see is the combined total, and you drill down into a single wallet when you want to know where a number comes from.

Satzo single-wallet drill-down for a demo wallet, showing that wallet's total, holdings, and its Aave V3 and Morpho Blue positions. All figures are demo data.

The question I actually open the app with is "what do I have?", not "what's in this particular address?" The wallet-level page is still there for the second question. It just isn't the front door.

What I got wrong: daily snapshots

The first version of the history chart was built on daily snapshots. A scheduled job recorded each wallet's balance once a day and stored it, and the chart plotted those stored values.

It was quick to build and it worked for the days it had data. The problem showed up everywhere else. A wallet added today had no past, because nothing had been recorded for it. Days with no snapshot got filled in with today's value, which draws a flat line that looks like history but isn't. Snapshots also only saw token balances, so DeFi positions were missing from the history completely.

The fix was to stop treating the stored balance as the record and treat the transactions as the record instead. Every transfer in and out of a wallet is an event. If you have the events and a historical price for each day, you can replay them and work out what the portfolio was worth on any date, including dates before the wallet was added to Satzo.

I rebuilt the history on that replay model. The portfolio chart, the single-wallet view and the dashboard now all read from it. Each historical value also keeps a record of how it was worked out, so when a price is missing for a day the chart marks that point as partial or unavailable instead of guessing.

If I started again I'd go straight to replay. Snapshots felt like the simple option. In practice they meant building a history feature twice.

What's still rough

Satzo is in beta, and the gaps are real:

  • Some history points are marked partial because a price or position detail isn't available for that day.
  • DeFi positions are part of the current total, but their history isn't captured the same way token balances are yet.
  • Only the protocols listed above get a proper breakdown. Everything else sits under "Other DeFi".

There's a lot more crypto functionality to come in Satzo, and I'll write those up here as they ship.

What's next

The next thing I want to fix is DeFi visibility. At the moment a position contributes to the total, but you can't see much about the position itself. I want Satzo to give much better visibility into each DeFi position, beyond its share of the total.