rotki

rotki.com
rotki

A self-hosted, opensource, privacy-first portfolio tracking and accounting tool for crypto and more. Support for all 3 major Operating systems and docker. The tool focus is on data self-sovereignty.

Crypto Payments Accepted Open Source

rotki Source Code

Author

rotki

Description

A portfolio tracking, analytics, accounting and management application that protects your privacy

#accounting#analytics#bitcoin#blockchain#cryptocurrencies#cryptocurrency-exchanges#cryptocurrency-portfolio#cryptocurrency-portfolio-tracking#ethereum#hacktoberfest#management#management-system#portfolio-tracker#tracking

Homepage

https://rotki.com

License

AGPL-3.0

Created

05 Mar 18

Last Updated

17 Jul 26

Latest version

v1.43.2

Primary Language

Python

Size

504,222 KB

Stars

3,949

Forks

740

Watchers

3,949

Language Usage

Language Usage

Star History

Star History

Top Contributors

Recent Commits

  • Lefteris Karapetsas (17 Jul 26)

    feat: decode GnosisDAO GIP-151 treasury redemption on gnosis chain

  • Konstantinos Paparas (17 Jul 26)

    feat(history): show raw event type/subtype hint in dev In dev builds only, render each action row's underlying eventType:eventSubtype combinations as a small muted line under the description. Helps developers map a user-facing action back to its raw type/subtype pair.

  • Konstantinos Paparas (17 Jul 26)

    fix(privacy): remove stray blue box on scramble toggle The scramble switch carried bg-rui-secondary styling left over from the old side-by-side toggle+multiplier pill layout. Since the controls are now stacked vertically it rendered as a stray solid blue box. Drop the wrapper classes so it matches the other switches.

  • Lefteris Karapetsas (17 Jul 26)

    fix: decode eigenlayer withdrawal completions with unknown queueing Fix unknown queing tx by matching the withdrawn funds from the completion transaction's own logs (strategy ExchangeRateEmitted / eigenpod RestakedBeaconChainETHWithdrawn), handling force-undelegated stakers whose queue tx is not tracked

  • Konstantinos Paparas (17 Jul 26)

    fix(pinned): keep pinned tabs across a logout Logging out resets every pinia store, which empties the rail. The persistence watcher faithfully wrote that emptied state through, so signing out destroyed the tabs it exists to restore. Restarting while logged in worked; logging out and back in did not. Skip persisting while logged out, so the logout reset cannot clobber what the next sign-in restores. Store the tabs per user while here. The rail records what someone was investigating rather than how they like their machine set up, so another user signing in on the same device should not inherit it. This follows the existing per-user storage idiom (see use-eth-staking-refresh). The width stays device-global: it describes the screen, like the ui language, and reveals nothing about its owner.

  • Konstantinos Paparas (17 Jul 26)

    feat(pinned): share a bottom sheet for panel details Opening a data issue from the pinned rail slid a 570px drawer out beside the rail, so the detail read as a second surface competing with the panel its list lives in. Show it as a bottom sheet over the panel body instead, which is what the match panel already did for potential matches. That made the behaviour a second consumer, so extract it: PinnedDetailSheet owns the scrim, the slide-up and the placement, and match moves onto it. The sheet is positioned absolutely rather than teleported. The rail keeps backgrounded panels alive with <KeepAlive>, and a deactivated panel's teleported content leaks out of its target, so a teleporting overlay is not usable inside a panel. That constraint lived only in the match panel's markup; now a new panel gets it by construction. Chrome stays with each panel: match keeps its compact title bar, while the issue detail brings its own header and action row. Only the behaviour is shared. The full data-issues page keeps its right-hand drawer, so the detail body moves to DataIssueDetailContent and both containers render it.

  • Konstantinos Paparas (17 Jul 26)

    feat(pinned): make balance divergence pinnable Balance divergence was reverted to a plain navigation drawer in #12591 because the old single-slot rail would silently evict an in-progress bisect when another panel was pinned. The multi-slot rail keeps every panel alive, so the search can now live in it without losing state. Register it in the pinned registry and drop the standalone drawer, the same shape data issues already follows: - add BALANCE_DIVERGENCE to PinnedNames and PinnedPanelProps (no props; it is a self-sufficient search tool, so it restores from persistence with an empty payload and refetches its own options) - add the registry row and a thin BalanceDivergencePinned host - switch BalanceDivergenceToggle from a local v-model to usePinnedPanel - delete BalanceDivergencePanel, whose focus-within/timeout workaround only existed to stop teleported autocomplete clicks from closing a temporary drawer; the rail is not one - drop the view's own header, since the rail tab strip is the single title/close/collapse bar

  • Yábir Benchakhtir (17 Jul 26)

    Merge pull request #12606 from yabirgb/docs Bump depencencies

  • Yábir Benchakhtir (17 Jul 26)

    Merge pull request #12604 from yabirgb/fixes-ql fix: validate user data directory paths

  • Yabir Benchakhtir (17 Jul 26)

    Update mcp version

  • Yabir Benchakhtir (17 Jul 26)

    Bump docs dependencies compatible with 3.14

  • Yabir Benchakhtir (17 Jul 26)

    fix: validate user data directory paths

  • Yábir Benchakhtir (17 Jul 26)

    Merge pull request #12602 from LefterisJP/eigenwithdrawal fix: decode eigenlayer post-slashing withdrawals

  • Lefteris Karapetsas (17 Jul 26)

    fix: docs build under python 3.12+ sphinxcontrib-httpexample 1.1 still builds ast.Str nodes which were removed in python 3.12, crashing sphinx while reading api.rst. Alias ast.Str to its drop-in replacement ast.Constant in conf.py until a fixed version of the extension is released.

  • Konstantinos Paparas (16 Jul 26)

    feat(pinned): redesign the pinned sidebar into a multi-slot rail Replace the ad-hoc single-slot pinning mechanism with a typed, multi-slot rail so panels no longer silently evict one another or lose in-progress state, and so every pinnable area is consistent by construction. Core: - Typed registry (`PINNED_PANELS`) maps each `PinnedName` to its component, label, icon and optional tab-strip actions; `usePinnedPanel(id)` is the single lifecycle API (typed props, pin/unpin/focus/collapse/toggle). - Store holds `pinnedPanels[] + activePinnedId` (cap 4, LRU) instead of one slot; `Pinned` is a discriminated union built through one `toPinned` util. Rail UX: - `PinnedSidebar` renders a tab strip (the single title/close/collapse bar) above a `<KeepAlive>`-wrapped active panel, so backgrounded tabs keep their state. Tabs scroll; the actions + collapse cluster stays pinned right. - Collapsed state is a right-edge icon mini-bar; the indicator shows the pinned count and toggles the rail. - Panels render body only (no per-panel headers); panel-specific controls (internal-tx settings) live on the tab strip via the registry. - Shared `PinnedPanelBody` owns the height/scroll contract; content gutter standardized to px-3 across every panel. Other: - Drop the data-issues overlay bridge (KeepAlive preserves its state). - Persist rail width + open tabs to localStorage; restore non-intrusively. - Pause the data-issues poll/refetch while its tab is backgrounded; bound the KeepAlive cache to the pin cap. Adds first-time unit coverage for the store, composable, registry, rail, indicator, persistence and highlight teardown. Full unit suite green.

  • Lefteris Karapetsas (17 Jul 26)

    fix: decode eigenlayer post-slashing withdrawals Support the SlashingWithdrawalQueued/SlashingWithdrawalCompleted events introduced by the eigenlayer slashing upgrade (ELIP-002). Also show the EIGEN strategy's bEIGEN underlying as EIGEN, match completion transfers emitted after the completed event via an action item and match natively restaked ETH sent by the user's eigenpod as a transfer to avoid double counting with validator withdrawals.

  • Yabir Benchakhtir (16 Jul 26)

    Vendor windows signal and remove pywin dep

  • Konstantinos Paparas (16 Jul 26)

    test: fix order-dependent leaks and test noise Make the unit suite order-independent under --sequence.shuffle and quiet its stderr, without changing any assertions or coverage. Isolation (17 specs): fresh pinia per test, beforeAll->beforeEach for state-mutating setup, dispose createSharedComposable watchers via effectScope/unmount, reset shared refs/mocks (mockReset over clearAllMocks for leaked implementations), reset the shared vue-router route query, clear sessionStorage, avoid fake-timer drift, and unify FilterDropdown wrapper handling. Verified green across 16 shuffle seeds (5524 tests). Noise: buffer consola (the app logger) per test and only replay on failure (VITEST_VERBOSE=1 to disable); add an MSW handler for queried_addresses (was hitting a real socket); silence lifecycle-hook Vue warnings via a shared withSetup helper; close the Dexie connection on scope dispose in use-database. Perf: skip the real 1s backoff sleep in use-task-monitor via fake timers.

  • Yábir Benchakhtir (16 Jul 26)

    Merge pull request #12541 from yabirgb/codex/python313 Move project to python 3.14

  • Yabir Benchakhtir (16 Jul 26)

    Avoid installing python again in docker build

  • Konstantinos Paparas (15 Jul 26)

    feat(settings): derive search from the registry The settings search is now fully derived from the settings registry: the per-tab getXTab builders and the hand-written search list are gone. A setting's registry `search` block drives both its search row and its scroll-target anchor, and each settings tab's route/label/icon comes from its page `nav` meta. SettingsItem resolves its DOM id (and fallback title) from `setting-key`; a composite item wrapping several settings under one anchor passes the representative key. Rows with no registry value (change password, purge data, rpc nodes, ...) live in a new `settingsActions` registry and resolve through a shared `anchorId(key)` helper, via `action-key` on a SettingsItem or `:id="anchorId('...')"` on a bare section. No template restates a SettingsHighlightIds value anymore. A derived invariant - every highlight id is owned by exactly one of the setting or action registries - replaces the hand-kept keyless allowlist. Adds unit coverage for the actions registry and the SettingsItem action-key path, plus an e2e spec that drives the search palette end to end.

  • Konstantinos Paparas (15 Jul 26)

    fix: use normal AppImage compression compression: 'maximum' (bf4c4602be) builds the AppImage squashfs with xz/LZMA. AppImage decompresses file blocks on demand at runtime, so every cold launch pays a heavy per-block decompress cost paging in the Electron/Chromium binary + app.asar, adding ~40s to startup. Switch to 'normal', restoring launch speed. Measured on a Linux x64 build (full package: Electron + app.asar + backend + colibri): maximum: 203 MB, slow start (~+40s) normal: 256 MB, fast start store: 256 MB (identical to normal for AppImage) The cost is a ~53 MB (~26%) larger download, paid once, versus a stall paid on every launch. 'store' gives no size benefit over 'normal' for AppImage, and electron-builder exposes no level between normal and maximum, so 'normal' is the fast option.

  • Konstantinos Paparas (15 Jul 26)

    test: adopt shared task/notification mocks in more specs Migrate the remaining verbatim useTaskHandler mocks (price/asset/history specs) onto mockUseTaskHandler, covering the invoke=false and cancelTaskByTaskType variants, and swap a throwaway notifications mock onto mockUseNotifications.

  • Konstantinos Paparas (15 Jul 26)

    test: add shared notifications and supported-chains mocks Add mockUseNotifications and mockUseSupportedChains helpers under tests/unit/utils/mocks/ with sensible defaults, and adopt them across four proof specs.

  • Konstantinos Paparas (15 Jul 26)

    test: add shared task-runner mock helper Extract the verbatim useTaskHandler mock (runTask invoke-then-delegate) into a shared mockUseTaskHandler helper under tests/unit/utils/mocks/, and adopt it in three proof specs.

  • fakkoweb (13 Jul 26)

    Clarify CoinEx discount fee assumption

  • fakkoweb (13 Jul 26)

    Handle missing CoinEx CET mapping

  • fakkoweb (12 Jul 26)

    Record CoinEx CET discount fees

  • Konstantinos Paparas (14 Jul 26)

    test(frontend): cover account management and migration Cover useBlockchainAccountManagement (single/multiple evm + account addition dispatch, task-running guard, no-new-address notify, xpub) and useAccountMigration (deferred/immediate migration, chain filtering).

  • Konstantinos Paparas (14 Jul 26)

    test(frontend): cover useAccountOperations Cover fetchAccounts (evm ens resolution, all-chains fallback), refreshAccounts (regular/eth2/non-tx-chain and eth2 validator scheduling), detectEvmAccounts, and status reset.

rotki Security

6.5/10

Repo Security Summary

Updated 29 Jun 26

  • Code-Review 0/10
  • Maintained 10/10
  • Dangerous-Workflow 10/10
  • CII-Best-Practices 0/10
  • Token-Permissions 10/10
  • Security-Policy 0/10
  • License 10/10
  • Binary-Artifacts 10/10
  • Packaging 10/10
  • Branch-Protection 8/10
  • Signed-Releases 0/10
  • Fuzzing 0/10
  • SAST 9/10
  • Pinned-Dependencies 9/10

rotki Website

Website

rotki

rotki is an open source portfolio tracker, accounting and analytics tool that protects your privacy.

Redirects

Does not redirect

Security Checks

All 65 security checks passed

Server Details

  • IP Address 136.244.105.88
  • Hostname 136.244.105.88.vultrusercontent.com
  • Location Amsterdam, Noord-Holland, Netherlands (Kingdom of the), EU
  • ISP Vultr Holdings LLC
  • ASN AS20473

Associated Countries

  • US US
  • NL NL

Safety Score

Website marked as safe

100%

Blacklist Check

rotki.com was found on 0 blacklists

  • AntiSocial Blacklist
  • Artists Against 419
  • Badbitcoin
  • Bambenek Consulting
  • CERT Polska
  • CoinBlockerLists
  • CRDF
  • CryptoScamDB
  • EtherAddressLookup
  • EtherScamDB
  • Fake Website Buster
  • MetaMask EthPhishing
  • NABP Not Recommended Sites
  • OpenPhish
  • PetScams
  • PhishFeed
  • PhishFort
  • Phishing.Database
  • PhishStats
  • PhishTank
  • Phishunt
  • RPiList Not Serious
  • Scam.Directory
  • SecureReload Phishing List
  • Spam404
  • StopGunScams
  • Suspicious Hosting IP
  • ThreatFox
  • ThreatLog
  • TweetFeed
  • URLhaus
  • ViriBack C2 Tracker

Website Preview

Website preview

rotki Reviews

More Secure Budgeting

About the Data: rotki

Change History

API

You can access rotki's data programmatically via our API. Simply make a GET request to:

https://api.awesome-privacy.xyz/v1/services/rotki

The REST API is free, no-auth and CORS-enabled. To learn more, view the API Docs or read the API Usage Guide.

Share rotki

Help your friends compare Secure Budgeting, and pick privacy-respecting software and services.
Share rotki and Awesome Privacy with your network!

View Secure Budgeting (7)