* fix(binance): let go of an asset the wallet no longer holds Reported: a coin that had been sold stayed in the crypto account, showing up alongside the ones still held. Two separate causes, both of which had to go. The holdings processor only ever wrote what Binance returned. Nothing removed what it stopped returning, and the account page reads one day's rows — so a coin sold between two syncs kept its place for the rest of the day. Of the nine provider holdings processors, only CoinstatsAccount's removes anything; this follows it. The removal is keyed on what the payload contains rather than on what was successfully imported. An asset whose price cannot be fetched is skipped, and deleting on that basis would turn a price outage into a vanished holding. The importer made it permanent. Every sub-importer swallows its own error and answers with an empty asset list, so a total outage reached the upsert looking exactly like an emptied wallet — and the upsert was skipped, leaving the previous payload in place for the holdings processor to re-import as today's holdings. An asset already sold came back on every sync, indefinitely. A complete outage now raises, so the sync fails instead of reporting a successful import of nothing, and an emptied wallet is written down rather than skipped whenever there is an account to correct. A blank payload and a missing one are no longer the same thing: a wallet nothing has reported on yet keeps its holdings, since removing them would be deleting on the strength of missing information. The import failure is also recorded through DebugLogEntry now, so support can see it against the connection rather than only in the application log. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016GTNba5qE5NwzaHzbp27ye * fix(binance): do not remove what an unavailable source never reported Review on #3234, two ways the new cleanup could delete live positions. A source that fails tells us nothing about what it holds, but the importer wrote only the sources that answered — and the holdings processor removes what is missing from that list. A transient margin error, or a key without margin permission, would therefore have deleted every margin position. Their last known assets are carried instead, and only while the source stays silent: once it answers, what it says is what stands, including an asset it has stopped reporting. Worse, the guard against a total outage could not fire. EarnImporter's two sub-requests each rescue to nil, so a double failure returned an empty asset list with no error at all — indistinguishable from an account holding no Earn positions. With spot, margin and futures all failing, `results.all?` was still false, the importer wrote an empty wallet, and the cleanup emptied the portfolio. Earn reports the double failure now, carrying both messages. Also from review: the account_provider lookup added for the debug entry walked a lazy has_one per account. It eager-loads. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016GTNba5qE5NwzaHzbp27ye * fix(binance): keep the Earn side that went silent Review on #3234. The carry-over works per source, and Earn is one source made of two calls — so a single failing call slipped through it. With flexible answering and locked failing, the result carried no error, nothing was carried, and the cleanup removed every locked position. A key without locked permission would have deleted them on the first sync. Reporting the whole source as failed would have been wrong the other way: it would discard the side that did answer, and freeze Earn entirely for anyone whose key can only read one of the two. Every asset already keeps its flexible and locked amounts apart, so the side that went silent is refilled from what it last reported while the working side stays fresh. Three tests: the silent side keeps its position, an asset held only on the silent side survives, and a single failure is still not reported as an outage. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016GTNba5qE5NwzaHzbp27ye * fix(binance): record a partly-read wallet where support can see it Review on #3234. A source failing on its own returns normally, so the import never reaches the rescue in BinanceItem#import_latest_binance_data that writes the debug entry. The sync reported success, and the only trace that part of the wallet went unread was an application log line — and none at all when there was nothing to carry. It goes through DebugLogEntry now, with the sources that were unavailable and what each of them said, per the repo's provider-sync guidance. The warning stays, since it names how many assets were carried, which the entry does not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016GTNba5qE5NwzaHzbp27ye * fix(binance): record an Earn endpoint that stopped answering Review on #3234. One Earn side failing does not fail the import, so the parent never reaches record_partial_failure — and /settings/debug showed nothing about an endpoint that had stopped answering, while positions were being carried precisely because of it. Same shape as the parent's entry: a provider_sync warning naming the endpoints that went silent and what each of them said. The per-endpoint errors were already collected for the double-failure message; they are keyed by endpoint now so the entry can say which one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016GTNba5qE5NwzaHzbp27ye --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Deutsch | Español | Français | 日本語 | 한국어 | Português | Русский | 中文
Sure: The personal finance app for everyone
Get involved: Discord • Website • Issues
Important
This repository is a community fork of the now-abandoned Maybe Finance project.
Learn more in their final release doc.
Backstory
The Maybe Finance (archived/abandoned repo) team spent most of 2021–2022 building a full-featured personal finance and wealth management app. It even included an “Ask an Advisor” feature that connected users with a real CFP/CFA — all included with your subscription.
The business end of things didn't work out, and so they stopped developing the app in mid-2023.
After spending nearly $1 million on development (employees, contractors, data providers, infra, etc.), the team open-sourced the app. Their goal was to let users self-host it for free — and eventually launch a hosted version for a small fee.
They actually did launch that hosted version … briefly.
That also didn’t work out — at least not as a sustainable B2C business — so now here we are: hosting a community-maintained fork to keep the codebase alive and see where this can go next.
Join us!
Hosting Sure
Sure is a fully working personal finance app that can be self hosted with Docker. Sure can be accessed from a browser, the macOS desktop app, the mobile app, API clients, and LLM agents. See Sure Clients for an overview.
Forking and Attribution
This repo is a community fork of the archived Maybe Finance repo. You’re free to fork it under the AGPLv3 license — but we’d love it if you stuck around and contributed here instead.
To stay compliant and avoid trademark issues:
- Be sure to include the original AGPLv3 license and clearly state in your README that your fork is based on Maybe Finance but is not affiliated with or endorsed by Maybe Finance Inc.
- "Maybe" is a trademark of Maybe Finance Inc. and therefore, use of it is NOT allowed in forked repositories (or the logo)
Performance Issues
With data-heavy apps, inevitably, there are performance issues. We've set up a public dashboard showing the problematic requests seen on the demo site, along with the stacktraces to help debug them.
https://www.skylight.io/app/applications/s6PEZSKwcklL/recent/6h/endpoints
Any contributions that help improve performance are very much welcome.
Local Development Setup
If you are trying to self-host the app, read this guide to get started.
The instructions below are for developers to get started with contributing to the app.
Requirements
- See
.ruby-versionfile for required Ruby version - PostgreSQL >9.3 (latest stable version recommended)
- Redis > 5.4 (latest stable version recommended)
Getting Started
cd sure
cp .env.local.example .env.local
bin/setup
bin/dev
# Optionally, load demo data
rake demo_data:default
Visit http://localhost:3000 to view the app.
If you loaded the optional demo data, log in with these credentials:
- Email:
user@example.com - Password:
Password1!
For further instructions, see guides below.
Setup Guides
- Mac dev setup
- Linux dev setup
- Windows dev setup
- Dev containers - visit this guide
One-click Install
Managed OpenClaw for Sure Finances
License and Trademarks
Maybe and Sure are both distributed under an AGPLv3 license.
- "Maybe" is a trademark of Maybe Finance, Inc.
- "Sure" is not, and refers to this community fork.
