--- url: /usage-guides/advanced/database-access.md description: >- How to open and query the encrypted rotki SQLite database using DB Browser for SQLite or sqlcipher CLI. --- # Accessing the database manually To detect potential problems with data or modify the state of the database, you might need to access it manually. Here’s a guide on how to do this using `DB Browser for SQLite` or `sqlcipher` CLI tool. ## Using DB Browser for SQLite 1. **Download and Install**: Get [DB Browser for SQLite](https://sqlitebrowser.org/dl/). It's available for Windows, macOS, and Linux. 2. **Starting the Program**: Launch the program with the SQLCipher functionality. 3. **Opening the rotki Database**: * Navigate to the rotki database in the [rotki data directory](/usage-guides/advanced/data-directory#rotki-data-directory). * Enter the password you use to unlock your rotki account to decrypt the database. 4. **Browsing and Modifying Data**: * Use the `Browse Data` tab to view the information. * Execute custom SQL commands if needed. However, be cautious and ensure you have double-checked commands with our team or are confident in what you are doing. * Always take backups before modifying the database to avoid inconsistent states. ## Using sqlcipher CLI Tool 1. **Installation**: * **Debian and Ubuntu Users**: Ensure you have a recent version of sqlcipher (v4 or later). The versions in the distribution repositories might be outdated. Use a [PPA](https://launchpad.net/ubuntu/+ppas) **(use at your own risk)** or follow this [StackOverflow thread](https://stackoverflow.com/questions/48105035/sqlite-browser-without-sqlcipher-support-in-ubuntu) to recompile `sqlitebrowser` with sqlcipher support. 2. **Opening the Database**: * Use the command line tool `sqlcipher` (not `sqlite3` since the database is encrypted). * After opening the database, specify the password to decrypt it by entering: ```sql PRAGMA key='your-secret-key'; ``` By following these steps, you can access and modify the rotki database securely. Always ensure to backup your database before making any changes. --- --- url: /usage-guides/settings/account.md description: >- Managing account passwords, database backups, data purging, and user settings import/export. --- # Account & Database Settings ## Account Settings ### Changing Password Choose the "User & Security" section to change the user password. ![Changing the user's password](/images/sc_user_password_change.png) ### Password Confirmation When using auto-login, you can enable periodic password confirmation to ensure you still remember your password. Toggle the setting on or off and set the confirmation interval in days (between 1 and 14). Disabling this setting will show a warning, since forgetting your password while using auto-login means losing access to your account. ## Database Settings ### Database Info & User Database Backups View information about your user and global database, such as directory, size, and version. ![Creating database backups](/images/sc_db_backup.png) Create new database backups, delete backups, and download backups locally. ### Purging Data rotki keeps a lot of data cached locally. Clean this data periodically from the "Manage Data" section in the settings. Remove specific exchanges by first removing any active API keys. ![Purging user data](/images/sc_purge_data.png) ### Exporting and Importing User Assets Use the export/import function to migrate user assets between computers. This function creates a zip archive of user assets for transfer. ![Importing user assets](/images/sc_custom_import_export.png) > \[!WARNING] > This archive cannot be used as a backup/restore across different versions of rotki since there is no guarantee of compatibility across versions. ### Reset Assets Database There are two options to reset the assets database: 1. **Soft Reset**: This option will not reset assets added by the user. 2. **Hard Reset**: This option will reset assets added by the user. ## Backend Settings Desktop app users can change the default data directory and log directory via the login screen. Click the cog wheel at the bottom right to view the backend settings dialog. ![Change the backend settings](/images/rotki_backend_settings.png) Select a new data directory, log directory, etc., and press "Save". Previously created accounts won't be accessible in the new location; move them manually. ### Advanced Backend Settings Modify the following settings in the advanced section: * **Max log size**: Maximum size (MB) of all logs for a single run. * **Max number of log files**: Maximum number of backup (rotated) logs for a single run. * **Instructions per SQLite context switch**: Specify instructions count for context switch between cooperative threads. Set to `0` to disable async DB access. * **Log from other modules**: Include log entries from dependent libraries, not just rotki. Disabled by default. --- --- url: /usage-guides/tax-accounting/accounting-rules.md description: >- Detailed explanation of every accounting setting in rotki including cost basis methods and tax-free periods. --- # Accounting Rule Options Explained This page explains every accounting setting in rotki in detail. These settings control how your transactions are processed when generating a [Profit/Loss Report](/usage-guides/history/pnl). You can configure them under **Settings → Accounting Settings** ([screenshot guide](/usage-guides/settings/accounting)). > \[!IMPORTANT] > rotki's default settings are based on German tax rules. Check with your tax advisor about what's required in your country and adjust accordingly. ## Cost basis method The cost basis method determines which acquisition is matched to a sale when calculating profit or loss. | Method | Full Name | How it works | Best for | | -------- | --------------------- | ----------------------------------------------- | -------------------------------------------------------------- | | **FIFO** | First In, First Out | The oldest acquisition is matched first | Most common default; required in many jurisdictions | | **LIFO** | Last In, First Out | The most recent acquisition is matched first | Jurisdictions that allow it; can defer gains in rising markets | | **HIFO** | Highest In, First Out | The highest-priced acquisition is matched first | Minimizing taxable gains (where allowed) | | **ACB** | Average Cost Basis | Uses the weighted average price of all holdings | Required in some jurisdictions (e.g., Canada, UK for shares) | **Example (FIFO)**: You bought 1 ETH at $1,000, then another 1 ETH at $2,000. You sell 1 ETH at $3,000. Under FIFO, the sale is matched to the $1,000 purchase, so your taxable gain is $2,000. **Example (HIFO)**: Same scenario — the sale is matched to the $2,000 purchase, so your taxable gain is only $1,000. ## Crypto to crypto trades **Setting**: `True` (default) or `False` Controls whether swapping one cryptocurrency for another is treated as a taxable event. **When `True`**: Each crypto-to-crypto swap generates "virtual trades" through your profit currency. For example, swapping 1 ETH → 2000 USDC when ETH is worth €3,000 and you originally bought ETH at €1,000 creates: * Virtual sell: Sell 1 ETH for €3,000 → PnL = €3,000 - €1,000 = **€2,000 gain** * Virtual buy: Buy 2000 USDC for €3,000 → PnL = €0 (acquisition, not taxable yet) **When `False`**: No profit/loss is calculated on the swap. The cost basis of the received asset inherits from what was given up. **Most users should**: Leave this as `True`. Most tax jurisdictions treat crypto-to-crypto swaps as taxable dispositions. ## Crypto spending This is part of the "Crypto to Crypto Trades" setting and controls whether spending crypto (on fees, purchases, etc.) triggers a cost basis PnL calculation. **When `True`**: When you spend crypto, rotki calculates both the loss from spending and any profit/loss from price changes since you acquired the asset. **Example**: You bought 1 ETH at €50. You later spend it on gas when ETH is worth €100. * Loss from spending: -€100 * Gain from price increase: €100 - €50 = €50 * **Net PnL: -€50** **When `False`**: Only the spending loss is counted. Net PnL: -€100. ## EVM gas costs **Setting**: `True` (default) or `False` Whether gas fees for on-chain transactions should be counted as a loss (expense) in PnL calculations. **When `True`**: Gas costs reduce your PnL as an expense. **When `False`**: Gas costs are ignored in PnL calculations. ## Tax-free period **Setting**: Number of days, or disabled If your country exempts crypto assets held for longer than a certain period from capital gains tax (e.g., Germany: 1 year = 365 days), enter the number of days here. **How it works**: When you sell an asset that you've held longer than the tax-free period, the gain is moved to the `pnl_free` column instead of `pnl_taxable` in the PnL report. ## Calculate past cost basis **Setting**: `True` (default) or `False` Whether rotki should look at all of your historical transactions (even before the report period) to determine the cost basis of assets sold during the report period. **When `True`**: If you bought ETH in 2020 and sell it in 2024, rotki uses the 2020 purchase price as the cost basis — even if your report period is only 2024. **When `False`**: Only events within the report period are considered for cost basis. This means older acquisitions are ignored, which can result in "no documented acquisition found" warnings. **Most users should**: Leave this as `True`. Turning it off means rotki can't trace the original purchase price for assets you've held for a long time. ## Omit ETH staking events **Setting**: `True` or `False` (default) Controls when ETH staking rewards become taxable. **When `True`**: Staking rewards are only considered taxable after the Ethereum merge and withdrawals are enabled (September 2022+). Earlier rewards are omitted from PnL. **When `False`**: All staking rewards are taxable at the time they are received, including pre-merge rewards. ## Include fees in cost basis **Setting**: `True` (default) or `False` Whether trading fees are added to the cost basis of the asset you're buying. **Example**: You buy 1 ETH for €1,000 and pay a €10 fee. **When `True`**: The cost basis of that ETH is €1,010. The fee is incorporated into the cost basis and will reduce your taxable gain when you eventually sell. **When `False`**: The cost basis is €1,000. The €10 fee appears as a separate spend event. ## Understanding accounting rule properties When you create or edit an [accounting rule](/usage-guides/settings/accounting#add-edit-accounting-rules), or when you look at the default rules in rotki's codebase, each rule has several properties that control how events are processed: ### Taxable Whether the event is subject to tax. If `False`, the event is recorded but doesn't contribute to taxable PnL. ### Count entire amount as spend For spending events, whether the full amount should be counted as an expense (negative PnL). **Example**: You spend 0.01 ETH (worth €30) on gas. * If `True`: The full €30 is counted as a loss. * If `False`: The amount is not counted as a direct loss (but cost basis PnL may still apply). ### Count cost basis PnL Whether to calculate the profit or loss between the asset's current value and its original acquisition price. This is the setting the user named "Count cost basis PnL" in the UI. It determines whether, in addition to counting the event as a spend/acquisition, rotki also computes the capital gain or loss since you originally acquired the asset. **Example**: You bought 1 ETH at €1,000. You later spend it when ETH is worth €3,000. * If `True`: rotki records a €2,000 capital gain (€3,000 - €1,000) in addition to the €3,000 spend. * If `False`: Only the spending amount is recorded; the difference from the acquisition price is ignored. **When you'd set this to `False`**: For events where the "spend" is not a real disposal — for example, depositing into a protocol. You're moving your asset, not selling it, so there's no capital gain to realize. ### Accounting treatment: Swap When multiple events are processed together (e.g., a trade that has both a spend and a receive event), the **Swap** treatment tells rotki to treat them as a single exchange. In a swap: 1. The spend side disposes of the asset (potentially triggering a capital gain/loss) 2. The receive side acquires a new asset at the current market value This is the default treatment for trades and DEX swaps. Without swap treatment, each side of a trade would be processed independently, which would produce incorrect PnL. **Example**: You swap 1 ETH (bought at €1,000) for 3,000 USDC when ETH is worth €3,000. * Spend side: Dispose of 1 ETH → capital gain of €2,000 * Receive side: Acquire 3,000 USDC at cost basis of €3,000 ### Accounting treatment: Basis Transfer **Basis Transfer** is used when you move assets between forms without realizing a gain or loss. The cost basis of the original asset is transferred to the new asset. This is used for events like token migrations (SAI → DAI), protocol deposits where you receive a receipt token, and similar non-taxable conversions. **Example**: You migrate 1,000 SAI (cost basis €900) to 1,000 DAI. * With Basis Transfer: The 1,000 DAI inherits the €900 cost basis. No taxable event. * Without Basis Transfer: The SAI disposal would trigger a gain/loss calculation, and DAI would be acquired at current market price. **When it's used**: Token migrations, wrapping/unwrapping (ETH ↔ WETH), receipt tokens from lending protocols, and other conversions where economic value doesn't change. ## Custom accounting rules You can create custom rules that override the defaults for specific combinations of: * Event type * Event subtype * Counterparty (protocol identifier) See [Add/Edit accounting rules](/usage-guides/settings/accounting#add-edit-accounting-rules) for how to create them in the UI. ### Limitations * **Counterparty must be a known protocol**: You can only create rules for counterparties that rotki recognizes (e.g., "uniswap-v3", "aave", "makerdao\_dsr"). Custom smart contract addresses cannot currently be used as counterparties for accounting rules. Support for custom counterparties is tracked in [rotki/rotki#9803](https://github.com/rotki/rotki/issues/9803). * **Rules are global**: A rule applies to all events matching the type/subtype/counterparty combination. For per-event overrides, use [special accounting rules for specific events](/usage-guides/settings/accounting#special-accounting-rules-for-specific-events). ## CSV export settings These settings control the format of exported PnL reports: * **Export Formulas**: Whether to export cell formulas (for spreadsheet calculations) or just the computed values. * **Have Summary**: Whether to include a summary section at the end of the CSV with totals and the rotki version/settings used. --- --- url: /usage-guides/settings/accounting.md description: >- Configuring accounting rules, cost basis methods, trade settings, and custom event rules for PnL reports. --- # Accounting Settings > \[!TIP] > For a detailed explanation of what each accounting option does (with worked examples), see [Accounting Rule Options Explained](/usage-guides/tax-accounting/accounting-rules). ![Customizing the accounting rules](/images/sc_accounting_custom_rule.png) In the accounting menu, you can customize application settings related to accounting calculations. These settings will affect the PnL report calculations. > \[!IMPORTANT] > Before changing any settings: > > 1. Review each option carefully > 2. Check with your tax advisor about what's required in your country > 3. Make adjustments based on their guidance **Current Default Settings:** * Based on German tax rules * Uses first-in/first-out (FIFO) method for calculating profits/losses * Treats crypto sales as tax-free after holding for 1 year You can change these settings to match your country's tax requirements. ### Add/Edit Accounting Rules ![Add new accounting rules](/images/sc_accounting_add_rule.png) You can add or edit accounting rules based on `Event type`, `Event subtype`, and `Counterparty`. ### Special Accounting Rules For Specific Events ![Special Accounting Rules](/images/sc_accounting_rules_special.png) You can set custom accounting rules for individual events or groups of events directly from the History Events page. This allows you to override the default accounting behavior for specific events. There are two ways to apply special rules: * Use the [Edit accounting rule](/usage-guides/history/events#edit-accounting-rule) menu for individual events * Use [Select multiple events](/usage-guides/history/events#select-multiple-events) to apply rules to multiple events at once ### Trade Settings ![Customizing the accounting trade settings](/images/sc_accounting_trade_settings.png) #### Crypto to Crypto Trades A setting to determine whether crypto to crypto trades or any events that spend crypto are taxable and should be taken into account. By default it's `True`. :::tabs \== Crypto to Crypto Trades > **Illustration:** > You trade your `1 ETH`, to get `11 USDT`. Current price of ETH is `10 EUR`, but you bought it when it was `5 EUR`. 1. If `True`, virtual trades are generated, and profits/losses are calculated based on the difference in asset prices. By making this trade, we will create two virtual trade, which are: * **Virtual Trade 1**: Sell `1 ETH` for `10 EUR`. PnL of this virtual trade is calculated as `the value when you sell this ETH (10 EUR)` minus `the value when you bought this ETH (5 EUR)` = `5 EUR`. * **Virtual Trade 2**: Buy `11 USDT` with `10 EUR`. PnL of this virtual trade is `0 EUR` because it's a buy. However, later on, when you trade this `USDT` with another crypto, point (1) will also be applied. > **Total PnL** = `5 EUR`. 2. If `False`, no virtual trades are generated, and no additional profits/losses are calculated. > **Total PnL** = `0 EUR`. \== Crypto Spending > **Illustration:** > You have `1` ETH that you bought with price `50 EUR`. Then you spend this `1` ETH for gas fees, and the price at the moment is `100 EUR`. 1. If `True`, when you use crypto for fees, donations, or purchases, the profit and loss (PnL) calculation shows two things: the loss from spending the crypto and any profit or loss from the difference between the asset's current price and its buying price. * **Loss from spending** = `-100 EUR`. * **Profit from price difference** = `100 EUR (spend price) - 50 EUR (buy price) = 50 EUR`. > **Total PnL** = `-100 EUR + 50 EUR` = `-50 EUR`. 2. If `False`, only the spending loss is considered. > **Total PnL** = `-100 EUR`. ::: #### EVM Gas Costs Specify if EVM transaction gas costs should be counted as a loss. #### Tax Free Period Specify if there is a tax-free holding period for crypto assets. #### Calculate Past Cost Basis Enable or disable calculating cost basis from all past events, even before the report period. #### Omit ETH Staking Events Specify if ETH staking events are taxable only after the merge and withdrawals are enabled or at the point of receiving. #### Use Asset Collections in Cost Basis When enabled, assets that belong to the same collection share cost basis. For example, if WETH and ETH are in the same asset collection, buying WETH and later selling ETH will use the WETH purchase as the cost basis. By default, this setting is `True`. #### Cost Basis Method Select the cost basis calculation method: `FIFO`, `LIFO`, `HIFO`, or `ACB`. #### Include Fees in Cost Basis A setting to determine if trade fees should be included in the cost basis of the asset being bought/sold. By default, this setting is `True`. > **Illustration:** > You bought `1` ETH for `10 EUR` and paid `1 EUR` fee. :::tabs \== True The fee event only reduces the amount of the fee asset paid. The actual fee is then used to determine the cost basis of the asset being bought or sold. > The cost basis of that ETH is `10 + 1` = `11 EUR`. This is where the fee is taken into account. \== False The above does not happen. > The cost basis of that ETH is `10 EUR`. But at the time of the trade you also have a spend event of `1 EUR` as fee. ::: ### CSV Export Settings ![Customizing the CSV export settings](/images/sc_accounting_csv_export_settings.png) #### Export Formulas Specify if formulas should be exported as formulas in the CSV or as actual values. #### Have Summary Specify whether the all\_events CSV export should include a summary of all events and the total profit/loss at the end. This summary would also include the rotki version and the settings used during the PnL report, making it easier to reproduce a report run. --- --- url: /usage-guides.md description: >- Reference for rotki account setup, sign-in, premium sync, data restoration, and upgrading between versions. --- # Accounts & Sync This page covers account creation, sign-in, premium sync, restoring backups, moving installations, and upgrading rotki. > \[!TIP] > **New to rotki?** Start with the [Quick Start Guide](/usage-guides/quick-start) for a step-by-step walkthrough from installation to your first PnL report. ## First Time Sign-Up When you start rotki, you'll see a sign-in/signup prompt. rotki is a local app, so your account only exists on your local system. Your account on [rotki.com](https://rotki.com/) is only for managing premium subscription payments. ![Creating a new account](/images/rotki_login_screen.png) To create a local account, press **Create Account**. If you have a premium subscription, you can link this local account using API keys. To restore an account with premium sync during account creation: 1. **Enable premium**. 2. Enable **Restore synced database**. 3. Enter your **API Key** and **Secret** (found on your account page at [rotki.com](https://rotki.com/)). Then click **Continue**. ![Enable premium sync](/images/rotki_create_account_enable_sync.png) Next, provide a profile name and a password: * **Profile Name**: An identifier for your local database. It doesn’t need to match any previous username or your premium subscription username on [rotki.com](https://rotki.com/). * **Password**: Do not forget this password. It encrypts all your local files. For a new account, you can add the premium API key and secret during setup or later using [Setup rotki premium](#set-up-rotki-premium). ![Creating a new account](/images/rotki_create_account.png) ## Restore a Backed-Up Database (Premium Users Only) ### Overview If you need to move your rotki database to a new device (e.g., if your old one was destroyed), you can manually do this as long as you have backups. As a premium user, you can also restore the encrypted database backed up on the [rotki.com](https://rotki.com/) server. ### Steps to Restore 1. **Follow Instructions**: Refer to the instructions in the previous section. 2. **API Key/Secret**: Add your API key/secret. 3. **Password**: Use the same password as your local user database. Do not use your rotki.com account password. > **Note**: If the password is not the same, the database won't open. ![Sign-up with existing premium subscription using a wrong password](/images/rotki_premium_signup_failed.png) ### Sync Data Refer to the [Sync data with rotki server](#sync-data-with-rotki-server) section to understand how the premium subscription works with multiple accounts/devices and how to sync your data with the rotki server. Syncing is disabled by default. > \[!IMPORTANT] Important Considerations > > * **User Database vs. Global Database**: Syncing only involves the user database, not the global database. > * **Global Database**: Contains all assets data, global address book for names, and historical prices. Premium syncing does not store your global database, so it is **essential** to manually move this database as well. You can see the guide of how to accomplish it [here](/usage-guides/#manually-move-global-database). Alternatively, you can use the [Exporting and importing user asset](/usage-guides/settings/account#exporting-and-importing-user-assets) function instead of moving the entire global database. ## Use an Account from a Different Installation ### Moving Data To move your data to another system or restore it: 1. Identify the [rotki data directory](/usage-guides/advanced/data-directory) on both the source and destination systems. 2. Move the entire data directory from the source system to the destination system. 3. Ensure both systems use the same version of rotki. ## Sign-In To sign in with your local rotki account, enter your profile name and password at the sign-in prompt. > \[!NOTE] > This is not the same as the online account you create at [rotki.com](https://rotki.com/) for a premium subscription. ## Set Up rotki Premium If you purchased a [rotki Premium](https://rotki.com/products/) subscription after creating your local account, you can activate it at any time by adding your API key and secret under **API Keys → rotki Premium** in the app. See [rotki Premium API Credentials](/premium/api-keys) for the full setup instructions. ## Sync Data with rotki Server ### Enable Data Sync To back up your data on the rotki Server: 1. Turn on "Allow data sync with rotki Server". This allows you to restore your data on any account/device using the same API key/secret and account password. ![Sync data with rotki Server](/images/rotki_premium_set_sync_data.png) ### Multiple Accounts/Devices If you use multiple accounts/devices, the one with the most recent login will upload the latest data to the rotki Server. Using the same account from another device may prompt you to replace your local database with the remote one. > \[!WARNING] > Do not run rotki on multiple accounts/devices at the same time, as this opens up the risk of several issues relating to data consistency. ![Replace local database with remote backup](/images/rotki_premium_replace_local_db_with_remote.png) ### Manually Move Global Database You can also manually move the global database containing assets from one system to another: 1. Locate the [rotki data directory](/usage-guides/advanced/data-directory) on the source system. 2. The global database is located at `/global/global.db` under the data directory above. Move it to the equivalent location on the new system. ![Manual DB sync](/images/rotki_premium_manual_db_sync.png) ### Manual Sync You can manually sync your database by clicking the "cloud" icon in the toolbar. ![Manual DB sync](/images/rotki_premium_automatic_db_sync_failed.png) If automatic sync fails, a message will appear. For messages like "Remote database larger than the local one," you can perform a "force push" by clicking the button. ## Upgrading rotki After a Long Time ### Upgrade Steps If you haven't used rotki for more than a year and a half and want to keep your data, follow these steps: 1. **Download rotki 1.25.2**: Get it [here](https://github.com/rotki/rotki/releases/tag/v1.25.2). 2. **Install and Log In**: Install rotki 1.25.2 and log into your account. This will update your database to version 34. 3. **Download the Latest Version**: Get the latest version [here](https://github.com/rotki/rotki/releases/). 4. **Install and Open**: Install the latest version and open your updated database. ### Supported Database Versions * **rotki 1.25.2 and Earlier**: Supports database versions 1 to 34. * **rotki 1.26.x and Later**: Supports database version 26 and above. --- --- url: /usage-guides/data-management/prices.md description: >- Adding custom latest and historical prices for assets that rotki cannot retrieve automatically. --- # Adding missing prices Sometimes rotki might be unable to retrieve prices for some assets. In order to always have the ability to show a price we provide two types of manual price additions in the menu `Manage Prices`: * **Latest price**: Will be the price displayed when we need to display the current price of an asset. * **Historical price**: The price used in a specific time in the past for an asset. ![Price management](/images/price_management.png) To add a new price you have to press the plus button. This will open the add form. ![Adding a new price](/images/price_management_add.png) There you can specify the assets, the price and the date of the price. Then you can proceed to save the entry. After saving you should be able to see the new entry. When a latest price is used it will be visually displayed in the UI. It will show an orange icon near the price, with a tooltip: "Manually defined price". ![Edited latest price UI indicator](/images/latest_price.png) --- --- url: /usage-guides/data-management/address-book.md description: >- Managing global and private address book entries to replace blockchain addresses with human-readable names. --- # Address Book You can manage the address book in `Manage Address Book` menu in the sidebar. rotki provides an address book for blockchains. This replaces addresses with names provided by the user across the application. You can click on `Save this name for all chains` to use the name for the provided address on all chains where that address appears. The address book is split into two different kinds: 1. **Global Address Book**: It replaces addresses with the names provided across the entire application irrespective of the user logged in. 2. **Private Address Book**: It replaces addresses with the names provided for the user currently logged in. It takes precedence over names found in the global address book. ![Adding entry to EVM address book](/images/add_evm_address_book.png) ![Displaying behaviour of an EVM address book](/images/display_evm_address_book_behaviour.png) > **Note:** The address resolution order can be configured in the general user settings. The default order is: > 1. Private Address Book > 2. Blockchain Account Labels > 3. Global Address Book > 4. Ethereum Tokens > 5. Hardcoded Mappings > 6. ENS names. ## Import multiple address books (CSV) You can add multiple address book entries at once with CSV import. You can find the menu in the three dots `⋮` menu here. ![Import Address Book Entries](/images/import_addressbook_entries.png) 1. The `address` field is **required**. 2. The `name` field is **required**. 3. The `blockchain` field is **optional**. You can find supported chain IDs in the [supported blockchains](/usage-guides/portfolio/accounts#blockchain-accounts) section. Leave it blank to add the entry to all chains. 4. The `location` field is **optional**. You can set it to either `global` or `private`. By default, it will be saved as `private`. --- --- url: /premium/api-keys.md description: >- Creating, managing, and securing rotki premium API key and secret credentials for app activation. --- # API Credentials rotki premium uses API credentials to connect your subscription to the rotki application. This guide explains how to create, manage, and secure your API credentials. ## What are rotki Premium API Credentials? The API Key and Secret are authentication credentials that: * Link your rotki app to your premium subscription * Enable premium features in the application * Allow cloud backup and sync across devices * Identify your account for device limit management ## Creating API Credentials After purchasing a subscription, you need to manually generate your API credentials: 1. Go to your [subscription page](https://rotki.com/home/subscription) 2. Navigate to the **API Credentials** section 3. Click the **Create** button 4. Your credentials will be generated and displayed: * **API Key** - Your public identifier * **API Secret** - Your private authentication token 5. You can view both credentials anytime from your subscription page ::: info Manual Generation Required API Credentials are not automatically created after payment. You must click the button to generate them for the first time. ::: ## Using API Credentials in the App After creating your API credentials, add them to rotki: 1. Open the rotki application 2. Navigate to **API Keys** → **rotki Premium** in the sidebar 3. Enter your **API Key** and **API Secret** 4. Click **Setup** ![Set up rotki premium API key/secret pair in an existing account](/images/rotki_premium_set.png) ## Managing API Credentials ### Viewing Your Credentials From your [subscription page](https://rotki.com/home/subscription): * Both your API Key and Secret are always visible * You can copy them anytime you need * You can see when the key was created ### Regenerating Credentials If you need to create new credentials: 1. Go to your [subscription page](https://rotki.com/home/subscription) 2. Click the **Regenerate** button 3. Your new API Key and Secret will be generated and displayed 4. Update credentials on all your devices ::: tip When to Regenerate * If you suspect your credentials have been compromised * If you want to revoke access from all devices ::: ## Security Best Practices ### Protecting Your Credentials ::: danger Keep Your Secret Safe * **Never** share your API Secret with anyone * **Never** post it in public forums or Discord * **Never** commit it to version control (Git, etc.) * **Never** send it via unencrypted channels ::: ### Storage Recommendations Store your API credentials securely: * Use a password manager (1Password, Bitwarden, KeePass, etc.) * Keep backups in a secure location * Don't save them in plain text files * Don't email them to yourself ### If Credentials are Compromised If you believe your API credentials have been exposed: 1. **Immediately** regenerate your API credentials from the [subscription page](https://rotki.com/home/subscription) by clicking **Regenerate** 2. Update all your legitimate devices with the new credentials 3. Monitor your account for unusual activity ## API Keys and Device Limits Each premium tier has a device limit. Each rotki app account where you add your API credentials is registered as a new device and counts toward your device limit. For more information about managing your devices, device limits, and what to do when you exceed your device limit, see the [Device Management](/premium/devices) documentation. ## Troubleshooting ### Invalid API Key/Secret Error If you see authentication errors: 1. Verify you copied the credentials correctly (no extra spaces) 2. Ensure your subscription is active (check [subscription page](https://rotki.com/home/subscription)) 3. Verify your API credentials are still visible on the subscription page 4. Try regenerating your credentials ### Can't See My API Key/Secret If you can't see your credentials on the subscription page: 1. Verify you're logged in to the correct rotki.com account 2. Ensure you've already generated API credentials (if not, click the generate button) 3. Refresh the page 4. Contact if the issue persists ### Premium Features Not Working If premium features aren't activating: 1. Verify API credentials are entered correctly in the app 2. Check your subscription is active and not expired 3. Ensure you haven't exceeded your device limit 4. Try removing and re-adding the credentials 5. Check the app logs for specific errors When premium is successfully activated in the app you should see a `rotki Premium is active` banner in the rotki Premium view. ![Active rotki premium](/images/active_premium.png) ### Multiple Devices Not Syncing If sync isn't working across devices: 1. Verify all devices use the same API credentials 2. Ensure "Allow data sync with rotki Server" is enabled (see [Sync Guide](/usage-guides/#sync-data-with-rotki-server)) 3. Check you haven't exceeded device limits 4. Manually trigger sync from the toolbar --- --- url: /usage-guides/data-management/assets.md description: >- Managing supported assets, adding custom tokens, merging duplicates, and whitelisting spam tokens. --- # Assets Management ## Inspecting list of assets You can now manage the list of supported assets by your local rotki instance. You can inspect the list of all supported assets, edit them, delete them or add new ones. They're divided into 3 sections; `Assets`, `Custom Assets`, and more sections (consist of `Manage CEX (Centralized Exchange) Mappings`, `Manage Counterparty Mappings`, `Newly Detected Tokens` and `Missing CEX Mappings` section). ![Manage the list of assets](/images/rotki_manage_assets.png) ### Token Detection Methods You can check token detection guide [here](/usage-guides/portfolio/accounts#token-detection) ## Adding/editing an asset ![Add or edit an asset](/images/rotki_add_edit_asset.png) ![Add or edit an asset icon](/images/rotki_add_edit_asset_icon.png) When you press the + button on the top right, or edit an existing asset you can see the Asset form. You can fill in the following fields: 1. The type of asset being created. This is required. 2. The chain where the token is located. This is required if the asset type is `EVM Token` or `Solana Token`. 3. The token kind. This is required if the asset type is `EVM Token` (options: `ERC20`, `ERC721`) or `Solana Token` (options: `SPL Token`, `SPL NFT`). 4. The token address. This is required if the asset type is `EVM Token` or `Solana Token`. 5. The token name. This is required. 6. The token symbol. This is required. 7. The token decimals. This is required if the asset type is `EVM Token`. 8. Coingecko identifier. This is optional, but highly recommended. If the asset is supported by coingecko you should get its coingecko identifier. This will allow the usage of coingecko as a price oracle and also will automatically pull the asset icon from coingecko. You can get the coingecko identifier for an asset by searching this list: https://api.coingecko.com/api/v3/coins/list . It may also be the same as the last part of the coingecko url. For example from `https://www.coingecko.com/en/coins/ethereum` we have `ethereum` as the identifier for ETH. 9. Cryptocompare identifier. This is optional but recommended. At least one of coingecko or cryptocompare should be given so that prices can be queried. If not given, the symbol of the asset will be used. If that fails, then cryptocompare is not used. To get the cryptocompare identifier, search for the coin in cryptocompare, visit its url and take it from there. For example for https://www.cryptocompare.com/coins/eth/overview/USD the identifier is `ETH`. It's always what comes after `coins`. 10. Optional fields section. This section will be explained below. 11. Preview of the icon. This section will show the icon you upload, or the current icon on edit mode. Additionally, on edit mode, there is also a button to fetch the latest icon. 12. You can upload an icon for the asset. Any of the common image extensions is accepted (png, jpg, jpeg, webp). The custom icon always takes precedence over the one auto-detected by coingecko. When you input the address of the token rotki will try to fetch its name, symbol and decimals and use them if they are available. There are also some other fields that are completely optional and expand if you press the (7) Optional Fields section. ![Optional information when adding an asset](/images/rotki_add_edit_token_optionals.png) 1. You can specify a timestamp at which the asset started to exist. This should be the token deployment timestamp for tokens. 2. If the asset is part of a protocol, specify it here. For example 'uniswap' for uniswap pool tokens, 'aave' for aTokens etc. 3. If the token is swapped for another token, specify it here. For example LEND was swapped for AAVE. 4. A token can have underlying tokens. Like a pool, or a token set. Here add the underlying token's address. 5. You have to specify the token kind. 6. And here add the underlying token's weight. 7. Here you can edit or delete underlying token address/weights. Note: The weight of the underlying tokens should add up to 100%. > \[!NOTE] > Underlying tokens only apply to asset type of `EVM Token`. ## Adding/editing a custom asset There is a lot of assets that rotki can't automatically track and they don't fit into traditional crypto assets. For example an ETF, real estate, ancient coins, valuable art etc. To represent those you can create custom assets, and then add a manual balance of those assets. ![Add or edit a custom asset](/images/rotki_add_edit_custom_asset.png) When you press the + button on the top right, or edit an existing custom asset you can see the Asset form. You can fill in the following fields: 1. The name to be given to the custom asset. This is required. 2. The type of custom asset being represented. It's just a string. The type field remembers all previously used types. This is required. 3. The note to be added to the custom asset. This is optional. ## Missing Mappings The missing mappings page shows assets that rotki encountered from exchanges or protocols but could not map to a known asset in its database. This typically happens when an exchange reports a balance for an asset that rotki doesn't recognize yet. Each entry shows the exchange/location, the unrecognized asset identifier, and any available details. Click the add button on a row to create a CEX mapping for that asset, linking it to a known asset in rotki. Once mapped, the entry is removed from the missing list and the asset will be tracked correctly. You can filter the list by exchange location or asset symbol. ## Manage CEX (Centralized Exchange) Mapping Users can link assets on exchanges to those recognized by rotki. If you encounter an error such as `Asset XXX is not supported` or `Found exchange balance result with unknown asset XXX. Ignoring it`, you may need to specify how the XXX asset should be recognized in rotki. ![Manage centralized exchange asset mapping](/images/rotki_manage_cex_mapping.png) ## Manage Counterparty Mappings Users can also link assets on any counterparty to those recognized by rotki. ![Manage counterparty asset mappings](/images/rotki_manage_counterparty_mapping.png) ## Newly detected tokens All newly detected EVM tokens will appear in the list of newly detected tokens. You should inspect this list often and accept valid tokens and reject spam assets by adding them to the ignored tokens list. ![Manage newly detected tokens](/images/rotki_manage_newly_detected_tokens.png) ## Merging two assets There are two possible situations where you might need to merge two assets into one. 1. You added a custom asset that was later officially supported on rotki. In this case you should merge your custom asset with the officially supported one. If you don't do this, you will see split balances between entries, especially for supported exchanges that will use the officially supported entry. 2. There was an issue and an Unknown asset notification is now visible. This can happen if you somehow end up deleting your global DB of assets. This way all your custom assets will be unknown. In this case you would need to re-add the deleted assets, and merge the old asset id that errors to the new one that you created. ![Merging of assets](/images/rotki_merge_assets.png) To merge two assets you can use the merge dialog by pressing the Merge Asset button in the Asset Management screen. In the dialog you can put the identifier of your custom or missing asset in the source field. For a custom asset, you can get the identifier using the copy button in the asset table. If you have a missing asset then you can copy it from the notification message Then you can go to the target field and search for the asset into which the source will be merged to. When both the source identifier and target asset are selected you can press the merge button. On a successful merge you will be notified to either re-login or refresh the balances manually to see the changes on the frontend. ## Special assets rotki allows you to track special assets like: 1. *Uniswap/Sushiswap LP tokens*: You can track LP tokens by adding them and using `UNI-V2` as protocol. This will make the app query balances and prices. As for now historical prices are not queried so you will need to add missing prices manually. 2. *Yearn vaults*: To add a yearn vault you need to add a new ethereum token and use `yearn_vaults_v2` as protocol. In addition you need to specify the underlying token that the vault uses with a 100% weight. ## Ignoring assets Specify which assets you own and would like to completely ignore from all calculations and balance queries. Any actions that involve these assets are ignored. You can ignore/un-ignore the assets by toggling the switch on the table. You can also ignore/un-ignore multiple assets by using the checkboxes. ![Asset overview page](/images/asset_overview.png) You can also ignore assets by clicking asset icons anywhere on the app, that will redirect you to this overview asset page. In this page, you can ignore or un-ignore a selected asset. It is also possible to ignore NFTs. To do this navigate to `Balances → NFT Balances` and toggle the ignore NFT switch. Then you can use the filter to view the ignored NFTs. ![Ignoring NFTs](/images/rotki_ignore_nfts.png) ## Mark asset as spam If you encounter an asset that you believe is spam (such as airdropped scam tokens), you can manually mark it as spam. This will add the asset to the ignored list and help keep your portfolio clean from unwanted tokens. To mark an asset as spam, navigate to `Manage Assets → Assets`, find the asset you want to mark, and click the arrow button beside the ignore/unignore switch to access the spam option. Once marked as spam, the asset will be treated the same as other ignored assets and will be excluded from all calculations and balance queries. Additionally, spam assets will not be decoded in history events. ![Mark asset as spam](/images/mark_as_spam.png) ## Whitelisting of ignored assets Spam assets are a plague in EVM chains. rotki has an automatic algorithm trying to match assets as spam to not bother the user with automatically ignoring them. You can see all ignored assets in `Manage Assets → Assets` and filter by ignored. A problem with automatic algorithms marking something as spam is that mistakes can be made and a legit token may be ignored. ![Filter ignored assets](/images/asset_filter_ignored.png) To solve this problem we added a whitelist which you can add assets to as can be seen below. Once an asset is added to the whitelist it will be removed from the ignore list and the automatic algorithm will not mark it as spam in the future. ![Whitelist asset](/images/asset_whitelist_menu.png) ## Whitelisting and Re-detecting Missing Tokens If a token doesn't appear in your balances, there are several ways to troubleshoot this. First you should check if it's been automatically or manually ignored. And then run a manual token detection. ### Check Token is not Ignored or Marked as Spam Go to the `Manage Assets -> Assets page`. Use the search to find the token by name or address. Verify if the token is ignored. If ignored, unignore it. If you did not ignore it on purpose click to whitelist it so the spam detection algorithm does not falsely flag it as spam. ![Example of managing assets and whitelisting a token in the Manage Assets page.](/images/manage-assets.png) --- --- url: /usage-guides/portfolio/balances.md description: >- Viewing exchange balances, adding manual balances, tracking NFTs, airdrops, and managing snapshots. --- # Balances ## Exchange Balances You can check all of the asset balances that you have in each connected exchange in the `Exchange Balances` sub-page. Clicking the `Add exchange` button takes you to the API Keys page where you can manage your exchange connections (see [Exchanges API Keys](/usage-guides/integrations/exchange-keys#exchanges-api-keys)). ![Exchange Balance](/images/sc_exchange_balances.png) ## Manual Balances You can add any type of asset to rotki, that may not officially supported yet. This includes things like: * Real estate * Stocks * Assets from unsupported blockchains or exchanges To add or edit a manual balance: 1. Go to the Manual Balances page 2. Click `Add Manual Balance` (top right) 3. Add a unique label 4. Select your asset from the dropdown 5. Add any tags you want 6. Enter the amount and location You can also filter the manual balances by `location`, `name` or `asset`. ![The manually tracked balances](/images/sc_manual_balances.png) By pressing the edit button for the account you can also add tags to the blockchain account. If you want to create a new tag or edit an existing one you can open the [tag manager](/usage-guides/data-management/tags) and choose the name, description and colors of the tag. ## NFTs rotki provides an NFT gallery where you can view the NFTs owned by your accounts. ![NFT Gallery](/images/sc_nfts.png) You have an overview of the total value of your NFTs in the application dashboard, on the NFTs table. ![NFT Value Dashboard](/images/sc_nf_balances_dashboard.png) An estimation of the value of the NFTs you own is counted into your total net worth. The estimation strategy is currently the maximum of either the floor price of the collection or the last sale of the NFT. If a manual price has been given this is always preferred. ![NFT Value Dashboard](/images/sc_nft_balances.png) If a price cannot be found for an NFT asset or if you want to change the calculated price estimate you can easily set the price for an NFT asset manually. You can do this by either clicking on the `>` button in the NFTs table in the dashboard or by going to `Blockchains & Accounts → NFT Balances`. And then click on the pen icon for the NFT you are interested in. For privacy concerns, it is possible to allow all or only a certain list of domains for images rendered, this can be done here by clicking on the icon highlighted below. More details here [Critical Privacy Vulnerability: Getting Exposed by MetaMask](https://medium.com/@alxlpsc/critical-privacy-vulnerability-getting-exposed-by-metamask-693c63c2ce94) The configuration menu: ![NFT Image Render Settings](/images/sc_nf_image_render_settings.png) Highlight details: 1. Link to blog post about image rendering and privacy. 2. Option to allow all NFT images to be rendered. 3. Option to allow only whitelisted domains. 4. If only whitelist, input list of allowed domains. 5. Save button. ![NFT Image Render Settings](/images/sc_nf_image_render_settings_whitelist.png) This will enable image rendering of only whitelisted NFT domains. ## Filtering by tags You can filter the tables by a combination of tags. ![Filter the accounts by tag](/images/filter_by_tag.png) Simply add the tags you wish to filter by in the filter textbox above the tables. ## Hide small balances You can filter out small balances and set the threshold yourself. By default, this setting will apply to all balance types (blockchain balances, exchange balances, and manual balances). You can uncheck the checkbox to apply the setting only to the current balances view. > \[!NOTE] > You need to press "Apply Changes" for the setting to take effect. ![Hide small balances](/images/hide_small_balances.png) ## Airdrops rotki can detect some airdrops for you ![rotki airdrops detection](/images/rotki_airdrops.png) The list of supported airdrops is pulled from the [rotki/data](https://github.com/rotki/data/tree/main/airdrops) repository and is updated automatically. New airdrops may be added over time without requiring an app update. Each airdrop shows one of the following statuses: * **Claimed** — The airdrop has been claimed. * **Unclaimed** — The airdrop is available but has not been claimed yet. * **Missed** — The claim window has expired. * **Unknown** — rotki can't determine the status. You need to check it yourself. ## Balances Snapshots The application automatically saves balance snapshots to your local database: * Occurs at login * Default interval: every 24 hours (configurable) To manually create a snapshot: 1. Click the `arrow down` near the graph 2. Select `Force Save` ![Force snapshots saves](/images/rotki_snapshot_forcing.png) ### Error Handling * Snapshots won't save if there are external source query errors * To save despite errors, select `Ignore Errors` ### Modify a snapshot point 1. Click on a snapshot point in the dashboard's net value graph 2. From the menu you can: * Edit snapshot data * Remove the snapshot * Download the snapshot ![Delete snapshot](/images/delete_snapshot_menu.png) ### Edit Snapshots Value * Click a snapshot point * Select edit * Modify values for assets and locations as needed ![Edit snapshot](/images/edit_snapshot_menu.png) ### Delete Snapshots Click a snapshot point and select delete to remove saved information. ### Download/Export Snapshots When exporting, four files are generated: 1. Two files for future data import 2. Two human-readable files for accounting: * `balances_snapshot`: Asset balances at snapshot time * `location_data_snapshot`: Value per location for each asset ### Import Snapshot Back To import previously exported snapshot data: 1. Use files with `_import` suffix 2. Click the `Arrow down` button near the chart 3. Select `Import` ![Import snapshots information](/images/import_snapshot.png) --- --- url: /usage-guides/settings/blockchain.md description: >- Configuring EVM chain settings, RPC nodes, transaction indexers, price oracles, and DeFi modules. --- # Blockchain & EVM Settings ## EVM ![EVM settings](/images/sc_evm_settings.png) #### Treat Staked ETH as ETH If enabled, ETH2 (staked ETH) will appear as ETH in the UI, and all tables and charts will combine the values of ETH and ETH2. #### EVM Chains for Automatic Detection Configure which EVM chains should not automatically detect tokens. By default, EVM chains detect activities of all registered EVM accounts in other EVM chains. ### Indexers rotki uses several indexers to identify which transactions belong to your tracked addresses. The order used for each chain can be adjusted in the default settings and will apply unless a specific chain configuration overrides it. For example you may want to avoid using etherscan on Optimism and Base if you do not have a paid API key for those networks. This lets you control which sources are queried and change the configuration if one of them is unreliable for a particular chain. In addition to querying historical events, indexers are used when detecting onchain activity, for example when you add a new address to all supported EVM chains or when the periodic task performs this check in the background. At the time of writing the only chain that cannot be queried for free is Binance SC because neither blockscout nor routescan are available and etherscan requires an API key under the Lite plan. Regarding the need for API keys: * Etherscan requires an API key in the free tier to perform API calls. * Blockscout does not require an API key and has a default limit of 10 requests per second. * Routescan offers a free tier comparable to etherscan and does not require an API key. ## Price Oracle Settings ![Change the order of price sources](/images/sc_price_oracle_order.png) Here, you can customize the order in which price oracles are queried, both for current and historical prices. This determines which price source to check first, second, and so on. Available price oracles include CoinGecko, CryptoCompare, Uniswap V2, Uniswap V3, DefiLlama, Alchemy, and custom (manual) prices. DeFi oracles like Uniswap V2 and Uniswap V3 use only on-chain information to get current prices. This makes querying a bit slower, but it relies solely on the Ethereum chain. Prices for some assets may differ from Coingecko or CryptoCompare, depending on the conditions of the pools at the time of the query. ### Oracle cache ![Creating a historical price cache](/images/sc_historical_price_cache.png) Querying historical prices from oracles such as CryptoCompare and CoinGecko is slow and can be slower due to rate limiting. rotki creates historical price caches during idle times. Request the creation of such a cache by going to the Oracle cache section, selecting the oracle, the from asset of the pair, the to asset of the pair, and then pressing "Cache pair prices". Manage existing historical price cache entries, inspect start and end dates, and delete caches if needed. ### Oracle Penalty Settings Configure penalty behavior for misbehaving price oracles at runtime. #### Oracle Penalty Duration The duration in seconds for which an oracle is penalized after exceeding the failure threshold. Default is 1800 seconds (30 minutes). #### Oracle Penalty Threshold Count The number of consecutive failures after which an oracle is penalized and temporarily skipped. Default is 5. ## RPC Node Setting This setting lets you change the nodes used to connect to blockchains. We give you a list of public nodes, but sometimes they are busy or down. You will see a green or red icon showing if a node is working. It is good to add more nodes and set their priority. We always try your own nodes first, then use some random public nodes if needed. If you don't have your own node, we use public nodes. The node's weight (percentage) shows how likely it is to be used. You can turn nodes on or off with the toggle button. ![Customizing the app's connection to EVM nodes](/images/rotki_nodes_management.png) In this menu you can also edit, delete or add more nodes. ![Add an EVM node](/images/rotki_nodes_management_addition.png) ### Local Nodes #### Connecting to a Kusama Client rotki attempts to connect to a local Kusama node running on the default port `9933`. If no client is running, blockchain queries will use an external service. #### Connecting to a Polkadot Client Set the RPC endpoint for a Polkadot node here. #### Connecting to an ETH Consensus Layer Beacon Node Set the RPC endpoint for the Ethereum consensus layer beacon node. If unreachable, beaconcha.in will be used. For DAppNode Ethereum validator users, find the RPC node setting in the DAppNode Package for the Execution Client. #### Connecting to a Bitcoin Mempool instance A local Bitcoin node can be used to query balances and transactions via [Mempool](https://mempool.space)'s API. [Mempool](https://github.com/mempool/mempool) is an open source project that can be self-hosted on Bitcoin nodes. It is readily available to install on many full-node distros such as Umbrel or Raspiblitz. Mempool uses port 4080 by default. Please include this when setting the endpoint (e.g. `http://localhost:4080`). Other custom ports should also work. Please note that transaction querying is currently not supported and historical transaction fetching will fail. Only address balance querying is supported when using a custom mempool instance. ## Module Settings Choose the "Module" section of the settings to customize the enabled modules and the queried addresses for each module. Enabling only the modules you use and specifying addresses improves querying speed. ![Managing module settings](/images/module_settings.png) ### Activating/Deactivating Modules View all modules in the table. Some are activated by default. Enable/disable a module by toggling the switch. Re-login for changes to take effect. ### Selecting Addresses ![Select address for modules](/images/module_settings_select_address.png) To limit querying to selected addresses, click the "edit/pencil" button on the module to select addresses. If no addresses are selected, rotki checks all eligible addresses, increasing query duration. --- --- url: /requirement-and-installation/build-from-source.md description: >- Build rotki from source for development or to run unreleased code, with backend, frontend, and packaging instructions. --- # Build from Source Building rotki from source is for contributors and for users who want to run unreleased code from git branches. If you just want to use rotki, the [packaged binaries](/requirement-and-installation/download) are easier. > \[!WARNING] > Don't switch between unreleased git builds and official releases on the same [data directory](/usage-guides/advanced/data-directory). Unreleased code has no forward-compatibility guarantees for the database schema. ## Prerequisites Before starting, ensure you have the following installed: * [Git](https://git-scm.com/downloads) * [Python 3.11.x](https://www.python.org/downloads/) * [uv](https://github.com/astral-sh/uv) — Python package manager * [Node.js](https://nodejs.org/en/) — check `frontend/package.json` `engines` for the exact supported range * [pnpm](https://pnpm.io/) — managed via `corepack` (see [Installing pnpm](#installing-pnpm)) * [Rust / Cargo](https://www.rust-lang.org/tools/install) — needed to build the Colibri service locally ## Get the source Fork the rotki repository on GitHub, then clone your fork locally: ```sh git clone https://github.com/your-user/rotki.git cd rotki ``` This guide assumes you checked out the `develop` branch, which is the default for contributors. ## Backend setup The backend setup is the same across Linux, macOS, and Windows — install `uv`, then run `uv sync` to create the development environment. OS-specific notes are below. ### Install uv **Linux and macOS:** ```sh curl -LsSf https://astral.sh/uv/install.sh | sh ``` **Windows (PowerShell):** ```sh powershell -c "irm https://astral.sh/uv/install.ps1 | iex" ``` ### Install dependencies From the rotki repo root: ```sh uv sync --group dev --group lint ``` This creates a `.venv` and installs the backend, dev, and lint dependency groups. ### Verify the backend Start the backend once to confirm it runs: ```sh uv run python -m rotkehlchen ``` You should see: ``` rotki REST API server is running at: 127.0.0.1:5042 ``` Stop it with `Ctrl+C` — we'll run everything together once the frontend is set up. ### OS-specific notes ::: tabs \== macOS Install [Homebrew](https://brew.sh/) first if you don't have it. Homebrew is used as a bootstrap for Python 3.11 and other toolchain dependencies. \== Windows 1. Install [Python 3.11](https://www.python.org/downloads/release/python-3117/) (64-bit). 2. Make sure Python is on your `Path`. If not, add both the root Python directory and the `Scripts` subdirectory via **Control Panel → System → Advanced system settings → Environment Variables**. 3. Test with `python` in a Command Prompt. If Windows opens the Store instead, disable the `python.exe` and `python3.exe` aliases under **App execution aliases**. 4. Install the [Visual Studio Build Tools](https://visualstudio.microsoft.com/vs/) with the **Desktop development with C++** workload. 5. After `uv sync`, download [miniupnpc for Windows](https://github.com/mrx23dot/miniupnp/releases/download/miniupnpd_2_2_24/miniupnpc_64bit_py39-2.2.24.zip) and copy `miniupnpc.dll` into the venv's site-packages directory. Find the path with: ```sh uv run python -c "import site; print(site.getsitepackages()[0])" ``` \== Linux No extra steps — `uv sync` handles everything. ::: ## Frontend setup The frontend lives under `frontend/` and uses pnpm. ### Installing pnpm The repo uses [corepack](https://nodejs.org/api/corepack.html) to manage pnpm. Enable it and corepack will automatically use the version pinned in `frontend/package.json` under `packageManager`: ```sh corepack enable pnpm pnpm --version ``` ### Install dependencies ```sh cd frontend pnpm install --frozen-lockfile ``` ### Run rotki in development mode From the `frontend/` directory: ```sh pnpm run dev ``` This starts the Electron app together with the backend, the Colibri service (if Cargo is available), and the frontend dev server. If `VITE_BACKEND_URL` is set in `frontend/app/.env.development.local`, the [development proxy](/contribution-guides/working-with-frontend#development-proxy) starts as well. For browser-only development (no Electron), use: ```sh pnpm run dev:web ``` See [Working with the Frontend](/contribution-guides/working-with-frontend) for environment variables, feature flags, and proxy configuration. ## Packaging To build a distributable package for your platform: ```sh # Install packaging dependencies uv sync --group packaging # Run the packaging script (works on all platforms) uv run python ./package.py --build full ``` ## Nix If you use [Nix](https://nixos.org/download), create a `flake.nix` at the repo root with the following: ```nix { description = "rotki project with uv-managed virtualenv"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05"; nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; flake-utils.url = "github:numtide/flake-utils"; }; outputs = { self, nixpkgs, flake-utils, ... }: flake-utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; python311 = pkgs.python311; nodejsWithPython = pkgs.nodejs.override { python3 = python311; }; nodePackages = pkgs.nodePackages.override { nodejs = nodejsWithPython; }; pnpmWithPython311 = nodePackages.pnpm; devShell = pkgs.mkShell { name = "rotki-dev"; buildInputs = [ pkgs.gcc pkgs.stdenv.cc.cc.lib pkgs.bash pkgs.git pkgs.lzma pnpmWithPython311 python311 pkgs.uv ]; shellHook = '' uv sync cd frontend pnpm install cd .. ''; }; in { inherit devShell; }); } ``` Then enter the development environment with: ```sh nix develop cd frontend pnpm run dev:web ``` ## Building a Docker image To build a Docker image from source using the repo's `Dockerfile`: ```sh docker build -t rotki . ``` ## Troubleshooting ### Blank screen when running the dev server If you get a blank screen on Electron when starting the dev server, check the console for a syntax-error message: ![Syntax Error](/images/troubleshooting_syntax_error.png) If you see one, go to `Help → Clear Cache`, then `View → Force Reload`. If the issue persists, follow the frontend [troubleshooting steps](/contribution-guides/vue-typescript#troubleshooting). ### Windows build tool errors If `uv sync` fails on Windows with errors like `Microsoft Visual C++ 14.0 is required`, the Visual Studio Build Tools aren't installed correctly. Make sure you selected the **Desktop development with C++** workload when installing — see the [prerequisites](#backend-setup) above. --- --- url: /usage-guides/integrations/calendar.md description: >- Using the calendar to track events, set reminders, and receive automatic alerts like ENS expiration. --- # Calendar rotki provides a calendar view where you can add and track events for your activities. You can also set reminders to perform some actions related to these events. You can see today's selected events and upcoming events on the right pane. ![Calendar view](/images/rotki_calendar.png) ![Add calendar event](/images/rotki_add_calendar_event.png) Here the non-obvious fields are: * **Notify me at event time**: Whether to also notify the user at the event time. If this setting is turned off, rotki will not notify you at the event time, other than the reminder you set beforehand. * **Delete event once it has passed**: Whether to remove events after the time has passed. We recommend turning this feature on to save space, unless you want to keep the event. ## Automatic events rotki can also create automatic events based on your on-chain activity. The events that rotki currently can check include: * ENS Expiration & Renewal You can customize how rotki handles automatic events by clicking the `setting` icon at the top. ![Automatic events setting](/images/rotki_calendar_automatic_events_setting.png) ## Event reminder The notification for the reminder of your event looks like this. ![Notification for the reminder](/images/rotki_calendar_reminder.png) ## Sync with google calendar You can sync rotki calendar events, to your Google Calendar for notifications and reminders. 1. Click the `Cog button` on the calendar page. ![Click cog button](/images/connect_google_calendar_1.png) 2. Click the `Connect to Google Calendar` button. It will open a page in your browser to continue the Google authentication. In Linux for the electron app, this will open a clean rotki browser window. This is due to known limitations in Linux at the moment. If you need to use passkeys, or already connected google accounts in your default browser copy paste the URL to it. The URL is`https://rotki.com/oauth/google?mode=app`. 3. Click `Continue with Google` and choose your Gmail account to continue. ![Continue with google](/images/connect_google_calendar_2.png) 4. After it's done, it will look like this. Click `Sync Now` to sync the events to Google Calendar on your selected account. ![Connected to google calendar](/images/connect_google_calendar_3.png) --- --- url: /contribution-guides/code-profiling.md description: >- Profiling rotki Python code using flamegraphs and viztracer to identify performance bottlenecks. --- # Code Profiling ## Python ### Flamegraph Profiling for Tests To use the flamegraph profiler, follow these steps: 1. Install the latest dependencies required for profiling: ```sh uv sync --group profiling ``` 2. Install the [flamegraph](https://github.com/brendangregg/FlameGraph) package in your system. Some OSes, such as Archlinux, have [ready-made packages](https://aur.archlinux.org/packages/flamegraph/). To profile a test run, add `--profiler=flamegraph-trace` to the pytest arguments. Once the test concludes, this will add a data file under `/tmp` with the data generated by the run. For example: `/tmp/20211127_1641_stack.data`. Then, you can run the flamegraph tool on that data to generate an SVG: ```sh flamegraph.pl --title "rotki-test graph" /tmp/20211127_1641_stack.data > profile.svg ``` Finally, open the SVG with any compatible viewer and explore the flamegraph. It will look like this: ![A flamegraph profiling example](/images/flamegraph_example.svg) ### Viztracer Viztracer is a good tool for profiling the actual code as it runs. It's included in the profiling dependency group. Then, run rotki's dev mode and add profiling arguments for Viztracer: ```sh pnpm run dev --profiling-args "-m viztracer --min_duration 0.2ms" ``` This will produce a `result.json` file in the main directory. The `--min_duration` argument is needed to avoid capturing data every nanosecond, which could result in a very large JSON file. You may need to adjust the arguments based on your needs. To open and study the file, you can use `vizviewer`. For example: ```sh vizviewer --flamegraph result.json ``` to get a flamegraph, or simply: ```sh vizviewer result.json ``` to get the normal view. For more information, check the Viztracer documentation. ### py-spy py-spy is a tool that generates a flamegraph of a running Python process and can attach to it. You can get it from [here](https://github.com/benfred/py-spy). You can run the developer version or a normal binary and find its PID with a command like: ```sh ps aux | grep rotki ``` Then, you can attach to it with a command like: ```sh sudo py-spy record -o py-spy.profile.svg --pid 60243 ``` assuming the PID is `60243`. You can also run rotki's dev mode directly by specifying the profile command and its arguments like this: ```sh pnpm run dev --profiling-cmd py-spy --profiling-args "record -o py-spy-profile.svg --" ``` Once done, there will be an SVG output at `py-spy.profile.svg`, which you can view with any SVG viewer, including a browser, and study the flamegraph. --- --- url: /contribution-guides/contribute-as-developer.md description: >- Developer contribution guide covering commit rules, linting, PR process, CLA, and development environment setup. --- # Contributing as a Developer Being an open-source project, we welcome contributions in the form of source code. To do that, you will have to work on an issue and open a Pull Request for it. In order for your Pull Request to be considered, it will need to pass the automated CI tests, and you will also need to sign the CLA (Contributor's License Agreement). ## Committing Rules For an exhaustive guide, read [this guide](http://chris.beams.io/posts/git-commit/). It's all really good advice. Some rules that you should always follow though are: 1. Commits should be just to the point, not too long and not too short. 2. Commit titles should not exceed 50 characters. 3. Give a description of what the commit does in a short title. If more information is needed, then add a blank line and afterward elaborate with as much information as needed. 4. Commits should do one thing; if two commits both do the same thing, that's a good sign they should be combined. 5. **Never** merge master on the branch; always rebase on master. To delete/amend/edit/combine commits, follow [this tutorial](https://robots.thoughtbot.com/git-interactive-rebase-squash-amend-rewriting-history). When pushing on a PR, the tags `[skip ci]` or `[ci skip]` can be used as part of the commit message to skip the run of all the CI jobs (lint, test, etc.). Lastly, we encourage using signed commits: ```sh git config commit.gpgsign true git config --global user.signingkey ``` For more information about signing commits, check out [Verify commit signatures](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification). ## Linting / Formatting Make sure to run `make lint` before pushing your commit. This runs ruff, mypy, and pylint on the code to make sure that formatting rules and common mistakes are not committed in the code. You can also bulk apply formatting changes to all files by running `make format`. To catch spelling mistakes before pushing, you can install [typos](https://github.com/crate-ci/typos). The CI will check for typos, so running it locally can help avoid CI failures: ```sh cargo install typos-cli # or other installation methods from the docs typos # check for typos typos -w # automatically fix typos ``` If you encounter false positives, add exceptions in `_typos.toml`: ```toml [default.extend-words] # Add exceptions for names, technical terms, etc teh = "teh" # Example: preserving "teh" as a surname ``` ## Where to make changes * If you want to contribute by fixing a bug, use the [bugfixes](https://github.com/rotki/rotki/tree/bugfixes) branch. * To add new assets, also use the [bugfixes](https://github.com/rotki/rotki/tree/bugfixes) branch. * Any other change can be made against the [develop](https://github.com/rotki/rotki/tree/develop) branch. Our releases work like this: * We release patches by merging the `bugfixes` branch to master and adding a new tag. * Normal releases are created by merging the `develop` branch to master and adding a new tag. ## Adding new assets to rotki To add new assets for rotki, you will have to edit [the SQL file](https://github.com/rotki/assets/tree/develop/updates) in the last update at the assets repository. SQL sentences for insertion differ depending on if we are adding an Ethereum token or other types of assets. More information about each type of asset and columns is available in the [readme file](https://github.com/rotki/assets#adding-evm-tokens). rotki uses [CAIP-19](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-19.md) to uniquely identify assets. So for example, if we wanted to refer to the Uniswap (UNI) ERC-20 token on the Ethereum mainnet chain, the correct identifier would be `eip155:1/erc20:0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984`. Once you have finished adding assets, it will be necessary to update the file containing metadata about the update. To do so, run the script: ```sh python tools/populate_infojson.py ``` This will update the file `info.json`. Finally, execute the tests to detect possible errors in the SQL sentences using: ```sh pytest tests ``` In order to do so, you will need to install the dependencies using `uv sync`. ### Get CoinGecko asset identifier In most cases, the CoinGecko asset identifier matches the URL one, for example "weth" for [WETH](https://www.coingecko.com/en/coins/weth). However, sometimes it doesn't, for example "sharering" for [SHR](https://www.coingecko.com/en/coins/sharetoken) ("sharetoken" in the URL). Lately, CoinGecko added the API id of the asset to the information provided for the asset. ![Obtain id for assets at CoinGecko](/images/gitcoin_id_position.png) This identifier mismatch can be detected by running [this test](https://github.com/rotki/rotki/blob/develop/rotkehlchen/tests/unit/test_assets.py#L91): ```sh python pytestgeventwrapper.py -xs rotkehlchen/tests/unit/test_assets.py::test_coingecko_identifiers_are_reachable ``` The test warns each mismatch suggesting the potential identifier (e.g., *Suggestion: id:sharering name:ShareToken symbol:shr*). This identifier can be checked via the **GET coins by id endpoint** on the [CoinGecko API explorer](https://www.coingecko.com/en/api#explore-api). The test also warns about any asset delisted from CoinGecko. In that case, add the delisted asset identifier to the [coins\_delisted\_from\_coingecko list](https://github.com/rotki/rotki/blob/80893e93a9b2e74287a5949c5fb742b5a068cecc/rotkehlchen/tests/unit/test_assets.py#L72). ### Get CryptoCompare asset identifier One important gotcha is to check for CryptoCompare asset prices. Unfortunately, you need to check the page of each asset in CryptoCompare. For example, for [$BASED](https://www.cryptocompare.com/coins/based/overview) you would need to check the page and then try to see the API call for USD price to see [if it exists](https://min-api.cryptocompare.com/data/pricehistorical?fsym=$BASED\&tsyms=USD\&ts=1611915600). If this returns something like: ```json { "Response": "Error", "Message": "There is no data for any of the toSymbols USD .", "HasWarning": true, "Type": 2, "RateLimit": {}, "Data": {}, "Warning": "There is no data for the toSymbol/s USD ", "ParamWithError": "tsyms" } ``` Then that means you have to check the CryptoCompare page and compare directly with the asset they have listed there. Like [so](https://min-api.cryptocompare.com/data/pricehistorical?fsym=$BASED\&tsyms=WETH\&ts=1611915600) and see that it works. Then you need to edit the CryptoCompare mappings in the code to add that special mapping [here](https://github.com/rotki/rotki/blob/239552b843cd8ad99d02855ff95393d6032dbc57/rotkehlchen/externalapis/cryptocompare.py#L45). If you don't find your asset on CryptoCompare, just put an empty string for the cryptocompare key. Like `cryptocompare: ""`. Hopefully, this situation with CryptoCompare is temporary and they will remove the need for these special mappings soon. ### Helpful commands * To get the checksummed Ethereum address, you can get it from the Python console using our code simply by doing: ```python >>> from eth_utils.address import to_checksum_address >>> to_checksum_address("0x9c78ee466d6cb57a4d01fd887d2b5dfb2d46288f") '0x9C78EE466D6Cb57A4d01Fd887D2b5dFb2D46288f' ``` ## Working with the develop branch The big changes to the code all happen in the `develop` branch. Those might include changes to the schema both in the user database and the global database. Errors related to partially migrated databases might manifest as errors in the UI when executing queries or failures to start the app or sign in. For working on develop instead of the normal `data` rotki directory, we use another in the root path called `develop_data`. To avoid losing information, we recommend copying your account from `data` to `develop_data` each time you pull new changes in develop, especially if you know that any DB schema changes happened. > \[!WARNING] > If your production data in `data` has syncing with rotki Premium enabled, please ensure that you disable this after copying to `develop_data`, otherwise there is a strong risk of syncing non-production data back to your production environment, and this could cause problems. ## Adding new Centralized Exchanges (CEXes) All centralized exchanges modules live in a separate python file under [here](https://github.com/rotki/rotki/tree/develop/rotkehlchen/exchanges). As an example of how to add a new CEX you can check the [Bitpanda PR](https://github.com/rotki/rotki/pull/3696/files). ### Add Location You should add a new value to the \[location Enum]\(https://github.com/rotki/rotki/blob/1039e04304cc034a57060757a1a8ae88b3c51806/rotke hlchen/types.py#L387) and also make sure that the value is mirrored in the DB's schema as seen [here](https://github.com/rotki/rotki/blob/1039e04304cc034a57060757a1a8ae88b3c51806/rotkehlchen/db/schema.py#L93-L94). Add it also in the `SUPPORTED_EXCHANGES` list [here](https://github.com/rotki/rotki/blob/1039e04304cc034a57060757a1a8ae88b3c51806/rotkehlchen/exchanges/manager.py#L31). Finally, don't forget to add it in the latest DB upgrade as seen in the Bitpanda PR linked at the start of this section. ### Create exchange module To add a new CEX you should create a new file with the name of the exchange all lowercase in [here](https://github.com/rotki/rotki/tree/develop/rotkehlchen/exchanges). It should have a class which should be the exact same name as the file but with the first letter capitalized. So if the module name is `pinkunicorn.py` the class name should be `Pinkunicorn`. That class should inherit from the `ExchangeInterface` and implement all the required methods. It should have an `edit_exchange_credentials()` and `validate_api_key()` to be able to validate and accept new credentials. It should have a `query_balances()` to return the current balances of the user in the exchange. It should have a `query_online_trade_history()` to query the trade history endpoint of the exchange for a given time range and save them in the database. It should have a `query_online_deposits_withdrawals()` to query the deposit/withdrawals history endpoint of the exchange for a given time range and save them in the database. Optionally it can have a `query_online_income_loss_expense` to parse any special data from the exchange that can create income/loss items for the user such as staking events. ### Add Asset Mappings Exchanges have assets listed by symbols. This is unfortunately inaccurate and has conflicts since there is no central crypto registry and there are too many crypto assets using the same symbol. We tackle this by having special mapping such as this one [here](https://github.com/rotki/rotki/blob/1039e04304cc034a57060757a1a8ae88b3c51806/rotkehlchen/assets/asset.py#L501). So you would add the mapping `WORLD_TO_MYNEWEXCHANGE`. Then you would create an `asset_from_mynewexchange()` function like [this one](https://github.com/rotki/rotki/blob/1039e04304cc034a57060757a1a8ae88b3c51806/rotkehlchen/assets/converters.py#L885-L898) for Bittrex. To find any assets listed in the exchange that are not mapped perfectly you would need to find and call the endpoint of the exchange that queries all assets. Then you need to write a test like [this](https://github.com/rotki/rotki/blob/1039e04304cc034a57060757a1a8ae88b3c51806/rotkehlchen/tests/exchanges/test_bittrex.py#L37-L51) which queries all assets and tries to call the `asset_from_bittrex()` function. If any asset is not mapped properly a warning should be raised so we the developers figure out a new asset is added and we need to map it. ### Add tests for the exchange You should write tests for all the endpoints of the exchange you implemented. To see what tests and how to write them, check the Bitpanda PR linked at the start of this section. You will generally need to: * Touch `rotkehlchen/tests/api/test_exchanges.py::pytest_setup_exchange()` * Add a new test module under `rotkehlchen/tests/exchanges/` * Add a new fixture for the exchange at `rotkehlchen/tests/fixtures/exchanges/mynewexchange.py` and expose it in `rotkehlchen/tests/fixtures/__init__.py` ## Adding new Ethereum modules This guide explains how to add a new Ethereum module into rotki and its corresponding transaction decoder and accountant. ### Add new module directory Each Ethereum module lives in [this directory](https://github.com/rotki/rotki/tree/develop/rotkehlchen/chain/ethereum/modules). To add a new module you should make sure the name is unique and create a new directory underneath. The directory should contain the following structure: ``` | |--- __init__.py |--- decoder.py |--- constants.py |--- accountant.py ``` Almost all of the above are optional. ### The decoder As an example decoder, we can look at [MakerDAO](https://github.com/rotki/rotki/blob/1039e04304cc034a57060757a1a8ae88b3c51806/rotkehlchen/chain/ethereum/modules/makerdao/decoder.py). It needs to contain a class that inherits from the `DecoderInterface` and is named `ModulenameDecoder`. Note: If your new decoder decodes an airdrop's claiming event and this airdrop is present in the [data repo airdrop index](https://github.com/rotki/data/blob/develop/airdrops/index_v2.json) with `has_decoder` as `false`, please update that also. #### Counterparties It needs to implement a method called `counterparties()` which returns a list of counterparties that can be associated with the transactions of this module. Most of the time these are protocol names like `uniswap-v1`, `makerdao_dsr`, etc. These are defined in the `constants.py` file. #### Mappings and rules The `addresses_to_decoders()` method maps any contract addresses that are identified in the transaction with the specific decoding function that can decode it. This is optional. The `decoding_rules()` define any functions that should simply be used for all decoding so long as this module is active. This is optional. The `enricher_rules()` define any functions that would be used as long as this module is active to analyze already existing decoded events and enrich them with extra information we can decode thanks to this module. This is optional. #### Decoding explained In very simple terms, the way the decoding works is that we go through all the transactions of the user and we apply all decoders to each transaction event that touches a tracked address. The first decoder that matches creates a decoded event. The event creation consists of creating a `HistoryBaseEntry`. These are the most basic form of events in rotki and are used everywhere. The fields as far as decoded transactions are concerned are explained below: * `event_identifier` is always the transaction hash. This identifies history events in the same transaction. * `sequence_index` is the order of the event in the transaction. Many times this is the log index, but decoders tend to play with this to make events appear in a specific way. * `asset` is the asset involved in the event. * `balance` is the balance of the involved asset. * `timestamp` is the Unix timestamp **in milliseconds**. * `location` is the location. Almost always `Location.BLOCKCHAIN` unless we got a specific location for the protocol of the transaction. * `location_label` is the initiator of the transaction. * `notes` is the human-readable description to be seen by the user for the transaction. * `event_type` is the main type of the event. (see next section) * `event_subtype` is the subtype of the event. (see next section) * `counterparty` is the counterparty/target of the transaction. For transactions that interact with protocols, we tend to use the `CPT_XXX` constants here. #### Event type/subtype and counterparty Each combination of event type and subtype and counterparty creates a new unique event type. This is important as they are all treated differently in many parts of rotki, including the accounting. But most importantly this is what determines how they appear in the UI! The mapping of these HistoryEvents types, subtypes, and categories is done in [rotkehlchen/accounting/constants.py](https://github.com/rotki/rotki/blob/17b4368bc15043307fa6acf536b5237b3840c40e/rotkehlchen/accounting/constants.py). ### The Accountant As an example accountant module, we can look at [MakerDAO](https://github.com/rotki/rotki/blob/1039e04304cc034a57060757a1a8ae88b3c51806/rotkehlchen/chain/ethereum/modules/makerdao/accountant.py). The `accountant.py` is optional but if it exists should also be under the main directory. It should contain a class named `ModuleNameAccountant` and it should inherit the `ModuleAccountantInterface`. What this class does is map all the different decoded events to how they should be processed for accounting. These accountants are all loaded in during PnL reporting. Each accountant should implement the `reset()` method to reset its internal state between runs. #### Event Settings mapping Each accountant should implement the `event_settings()` method. That is a mapping between each unique decoded event type, identified by `get_event_type_identifier()` and its `TxEventSettings()`. So essentially determining whether: * `taxable`: It's taxable * `count_entire_amount_spend`: If it's a spending event if the entire amount should be counted as a spend which means an expense. Negative PnL. * `count_cost_basis_pnl`: If true then we also count any profit/loss the asset may have had compared to when it was acquired. * `take`: The number of events to take for processing together. This is useful for swaps, to identify we need to process multiple events together. * `method`: Either an `acquisition` or a `spend`. * `multitake_treatment`: Optional. If `take` is not `1`, then this defines how we treat it. It's always a swap for now, so `TxMultitakeTreatment`. * `accountant_cb`: Optional. A callback to a method of the specific module's accountant that will execute some extra module-specific pnl processing logic. The MakerDAO accountant linked above has some examples for this. #### Multiple submodules The modules system is hierarchical and one module may contain multiple submodules. For example, Uniswap having both v1 and v3 each in their own subdirectories as seen [here](https://github.com/rotki/rotki/tree/develop/rotkehlchen/chain/ethereum/modules/uniswap). ## Add a new language or translation ### Add new language The translation files are located [here](https://github.com/rotki/rotki/tree/develop/frontend/app/src/locales). They are saved with the format `{language_code}.json`. You can see the list [here](https://www.w3schools.com/tags/ref_language_codes.asp). If you want to add a new language, you need to create a new language file with that format, and then [fill it](#add-or-edit-a-translation). You also need to update the frontend mapping that is defined at this [enum](https://github.com/rotki/rotki/blob/f57522baa737854e6affcbe57bada2b81c4dee83/frontend/app/src/types/frontend-settings.ts#L112), and these [entries](https://github.com/rotki/rotki/blob/f57522baa737854e6affcbe57bada2b81c4dee83/frontend/app/src/data/supported-language.ts). The `countries` field will be used to show the country's flag on the app. You can see the list [here](https://www.w3schools.com/tags/ref_country_codes.asp). ### Add or edit a translation rotki does translation using [Vue i18n](https://kazupon.github.io/vue-i18n). rotki's main language is `English`. The language file for it is [here](https://github.com/rotki/rotki/blob/develop/frontend/app/src/locales/en.json). To fill in the translation for another language, you should pay attention to the following things: 1. The `JSON` structure from the `English` language file is absolute, meaning you can't change the JSON structure (the keys), because this is how rotki reads which value to use. So for translations of other languages, please follow the same structure as the `English` language JSON file. For example: * **en.json** ```json { "exchange_balances": { "add_exchange": "Add exchange", "click_here": "Click here" } } ``` * **es.json** ```json { "exchange_balances": { "add_exchange": "Añadir intercambio", "click_here": "Haga clic aquí" } } ``` 2. You may notice that there are some words that are wrapped inside curly brackets, for example the word `length` in the sentence `Use total from {length} asset(s) value`. This is how rotki inserts a variable inside a sentence. You **must** keep this variable name, when translating to a different language. What you can do though is to reposition the variable inside the sentence. For example: * **en.json** ```json { "total": { "use_calculated_asset": "Use total from {length} asset(s) value: " } } ``` * **es.json** ```json { "total": { "use_calculated_asset": "Utilice el valor total de {length} activos: " } } ``` 3. For missing keys from other language files, by default it will use the value of the master file which is `English`. ## Add a new Airdrop To add a new airdrop in the DeFi/Airdrops section, go to the [data repo here](https://github.com/rotki/data/tree/develop). * Add the entry in `airdrops/index_v2.json` under the `airdrops` field. * If the token is new and is not expected to exist in the userDB and globalDB then `new_asset_data` should be added in the index. * If the asset's icon is not present in the `rotki` repo, it should be added in the `airdrops/icons` directory, with its path provided in its airdrop's index entry. If it's present, simply mention its name in the `icon` field. * If no decoder is present to decode the claiming event of this airdrop, add a `has_decoder` field in the entry with the value as `false`. ### Adding Token Airdrops with a CSV * The CSV's header should have the first column as `address` and the second column as `amount`. * The amounts should be normalized according to their decimals. * Create a Parquet file from the CSV using `python scripts/csv_to_parquet.py ` and remove the CSV. * Move the Parquet file in the `airdrops/` directory, with its path provided in its index entry. ### Adding Token Airdrops with an API * Add the API URL under the `api_url` field, with an `{address}` placeholder. This `{address}` will be replaced by the user's address at the time of checking the eligibility. * Add the `amount_path` in the form of a string with `/` separated fields. The returned JSON from the above API will be parsed using this path by reading each separated field from left to right, down the JSON. At the end, it should reach the amount of tokens, for which the user's address is eligible. --- --- url: /usage-guides/history/pnl.md description: >- Generating profit/loss reports with FIFO, LIFO, HIFO, or ACB methods and exporting results. --- # Creating a profit/loss report > \[!TIP] > **New to rotki?** If you're looking for a step-by-step guide to doing your crypto taxes, start with the [Tax Accounting Guide](/usage-guides/tax-accounting/guide) which walks you through the entire workflow. This page covers the PnL report feature in detail. rotki helps you track your cryptocurrency profits and losses (PnL) by analyzing your trading history and other transactions. Here's what you need to know about how these reports work: ## Key Features ### Multiple Accounting Methods You can choose how rotki calculates your profits: * **FIFO (First In - First Out)** - Default method: Assets bought first are sold first * **LIFO (Last In - First Out)** - Most recently bought assets are sold first * **HIFO (Highest In - First Out)** - Highest-priced purchases are sold first * **ACB (Average Cost Basis)** - Uses the average purchase price of all your assets ### Tax-Free Period Support If your country has tax-free holding periods (like Germany's 1-year rule), you can set this in rotki. Just go to "Accounting Settings" to specify the period in days. ### Smart Balance Tracking When you generate a report for a specific time period, rotki is smart about your previous holdings. For example: * You traded Bitcoin from 2017 to 2019 * You had 0.1 BTC on December 31, 2017 * If you generate a report for 2018-2019, rotki will include that 0.1 BTC as your starting balance This ensures your reports are accurate even when looking at specific time periods. ## Creating Your PnL Report ![View profit/loss report list](/images/sc_pnl_report.png) ### Step-by-Step Guide 1. Find and click the `Profit and Loss Report` button in the left menu 2. Select your preferred time period: * Choose from preset periods * Or click "Custom" to set specific start and end dates 3. Click `Generate` to create your report ### Important Notes * Report generation might take a few minutes, especially for longer periods * You can review your current accounting settings in the "Accounting settings" section * Having problems? Check our [troubleshooting guide](/usage-guides/history/pnl#pnl-report-creation-problems) ### Managing Your Reports * All your previously generated reports are visible on the same screen * You can view, download, or delete old reports * **Free Account Limit**: You can store up to 20 reports > \[!NOTE] > Before generating a new report, make sure all your transactions are properly imported and your accounting settings are correct to ensure accurate results. ## Results of the PnL report Once done you have an overview of the profit/loss for the given period, how much of that is taxable, and how much each taxable event category contributes to the total. ![Overview of the profit/loss report](/images/sc_pnl_report1.png) Additionally below the overview you get a table containing all of the events that were taken into account in the calculation along with how much of the `profit_currency` you lost or gained through that event. ![Event list of the profit/loss report](/images/sc_pnl_report2.png) Finally you can get a CSV export by pressing the "Export CSV" button. This export is meant to be imported into Google Sheets. Press the button and then choose a directory to write the CSV files to. Once done you can import the CSV files into Google Sheets via its import menu. > \[!IMPORTANT] > CSV export only works for the latest report generated in the active session. Following are definitions for the all\_event document's columns * `type` is a string describing the type of event a user engaged in, e.g. in "I buy ETH for EUR", buy is the `type`. * `location` is a string describing the location the event occurred at. For example "kraken" for kraken trades. * `asset` is a string identifying the asset an event was paid in, e.g. in "I bought 1 ETH for 100 EUR", EUR is the `asset`. * `free_amount`: is a number specifying the amount of `asset` that won't be taken into consideration for tax purposes. * `taxable_amount`: is a number specifying the amount of `asset` needed to be taken into consideration for tax purposes according to the accounting settings, e.g. "I sold 1 ETH for 120 EUR", 1 ETH is the `taxable_amount`. * `timestamp` is a string containing the date and time an event was executed. * `price` is `asset` price in `profit_currency` at the time the event was executed. * `pnl_free` is a number describing the amount of `asset` converted to the user's `profit_currency` that won't be taken into consideration for tax purposes. * `pnl_taxable` is a number describing the amount of `asset` converted to the user's `profit_currency`. Note that rotki additionally subtracts an exchange's trading fees from this number. * `cost_basis` If this is a spending event, this field contains information about where the amount that is spent came from according to the user's setting. Which buys contributed to this spend. If not enough information is known then this is also stated. * `notes` Information about the event. > \[!NOTE] > To learn more about `profit_currency` or to adjust it, see the section [change profit currency](/usage-guides/settings/general#profit-currency) Results from past profit and loss reports are saved so the user can later review them without the need to run a new execution. ![Profit and loss reports from past executions](/images/sc_pnl_saved_reports.png) ## Cost basis Cost basis is a really important aspect of accounting. For each sell event it lets you know what was the price at which the sold asset was acquired depending on a number of settings. Cost basis is calculated in rotki for all trades/events we support. Trades/events that rotki recognizes are: * All trades performed in our supported centralized exchanges * All trades done in our supported AMMs. As of this writing this is uniswap, sushiswap, balancer. * All manual trades inserted by the user. For all those trades you can see the cost basis when you create a profit loss report by: 1. Either navigating to the trade in the generated table after the PnL report and pressing the arrow to show more details. ![Cost basis in PnL report table](/images/sc_pnl_reports_costbasis.png) 2. Export the report to CSV and import it in a spreadsheet tool. We have tested it works with google spreadsheets and libreoffice. The cost basis column contains the info you seek. ![Cost basis in PnL report spreadsheet](/images/sc_pnl_reports_costbasis_spreadsheet.png) ## PnL report creation problems ### No documented acquisition found It's possible that rotki is not able to find an acquisition event for a sale. In which case it will warn you and ask you to fix it. ![Missing acquisitions found for asset](/images/sc_pnl_missing_acquisitions.png) This can happen for many reasons. The asset may have been acquired in a non-supported exchange/protocol, some event not detected etc. The way to fix it is to [add a history event](/usage-guides/history/events#add-edit-events) (such as a Swap or Receive event) to tell rotki how you acquired that asset. ### Event counted as taxable / count as spend where they shouldn't If you have an event that is counted as taxable / counts as spend when it shouldn't, you may need to edit the event type / subtype of the event. Read: [Common customization](/usage-guides/history/events#common-customization) ### PnL report generation gets stuck There are some known reasons why PnL report generation gets stuck: 1. If you have a Binance API key registered, please check these notes about [Binance API key rate limiting](/usage-guides/integrations/exchange-keys#market-pairs-required) If your PnL report is stuck for a different reason, contact us in [Discord](https://discord.rotki.com) ### Error when importing CSV formulas to Google Docs This is caused by the different Google Doc language configurations. Simply change the language on Google doc to United States. This can be done in File > Spreadsheet settings > General > Locale ### Timeout or price not found for timestamp ![Missing prices asset](/images/sc_pnl_missing_prices.png) It's possible that rotki is not able to find the price of assets. You have to input the price manually, otherwise the event will be skipped from pnl reports. For example if you are creating a GBP profit/loss report and the asset is GNO then make sure to create the GNO -> GBP historical price cache. You can add the prices on the spot, or open the [oracle cache](/usage-guides/settings/blockchain#oracle-cache) from the settings. ### The result of the generated PnL report is not what you expected. The results of the generated PnL report can vary depending on the [accounting settings](/usage-guides/settings/accounting). Check if any settings align with unusual treatments for your events, so you can adjust the settings to resolve the issue yourself. If you have any question or are confused about the settings, feel free to send us a message on [Discord](https://discord.rotki.com). ### Seeking help with complicated errors during PnL report generation ![Export PnL debug data](/images/sc_pnl_export_debug_data.png) It's possible that many errors could occur during the PnL report generation due to certain event(s) not accounted for properly. In such a scenario if all else fails, exporting the PnL debug data allows us to fully replicate the issue encountered and find a solution. > \[!WARNING] > Only share PnL debug data with the developers as it may contain sensitive information. --- --- url: /usage-guides/portfolio/dashboard.md description: >- Overview of the rotki dashboard showing total balance, net value graph, balance breakdowns, and asset holdings. --- # Dashboard The dashboard is the first page you see after logging into rotki. It provides a high-level overview of your entire portfolio across all tracked accounts, exchanges, and manual balances. ![rotki Dashboard](/images/rotki_dashboard.webp) ## Progress Indicator At the top of the dashboard, a progress indicator shows the status of ongoing operations such as balance queries, history event fetching, and historical balance processing. This bar appears automatically when rotki is working and can be dismissed. ## Total Balance Your **Total Balance** is displayed in your configured [profit currency](/usage-guides/settings/general#profit-currency). This is the combined value of all your assets across every tracked source — blockchain accounts, exchange balances, and manual entries. Below the total, a change indicator shows: * A **green arrow up** with the percentage and absolute gain if your portfolio increased * A **red arrow down** with the percentage and absolute loss if it decreased * A **gray horizontal arrow** if there is no change The change is calculated relative to the earliest snapshot in the selected timeframe. ## Net Value Graph The graph visualizes your portfolio's total value over time, based on saved [balance snapshots](/usage-guides/portfolio/balances#balances-snapshots). ### Interacting with the Graph * **Hover** over the graph to see the exact balance and date at any point * **Click** on a snapshot point to open the snapshot management dialog (edit, delete, or download) * **Double-click** to reset the zoom level * **Scroll wheel** to zoom in or out on the data * **Drag** to pan across the timeline ### Timeframe Selection Use the buttons above the graph to switch between timeframes: * **1W** — Last week * **2W** — Last 2 weeks * **1M** — Last month \[Premium] * **3M** — Last 3 months \[Premium] * **1Y** — Last year \[Premium] * **All** — Full history since your first snapshot \[Premium] > \[!NOTE] > Free users can access the 1W and 2W timeframes. The longer timeframes (1M, 3M, 1Y, All) require a [premium subscription](/premium/). > Timeframe buttons are also disabled if there are not enough snapshots to cover that period. ### Snapshot Controls The snapshot dropdown button (next to the graph) provides: * **Force Save** — Manually trigger a balance snapshot. Shows when the last snapshot was taken. * **Ignore Errors** — A checkbox to save snapshots even if some external service queries failed. This setting persists across sessions. * **Import Snapshot** — Upload previously exported snapshot CSV files (balance snapshot file + location data snapshot file). After import, rotki will log you out to apply the changes. For more details on managing snapshots, see [Balance Snapshots](/usage-guides/portfolio/balances#balances-snapshots). ## Balance Summary Below the graph, three columns break down your balances by source: ### Exchange Balances Shows the total value held in each connected exchange. Click on an exchange name to navigate to its detailed balance view. If no exchanges are connected, an add button is shown to link one. To add an exchange connection, see [Exchange API Keys](/usage-guides/integrations/exchange-keys). ### Blockchain Balances Lists each blockchain network where you have tracked accounts, with the total value per chain. Click on a chain name to view the accounts on that specific network. The refresh button on this card has a dropdown with two options: * **Only Refresh Balances** — Re-queries balances for all tracked addresses (default) * **Redetect Tokens** — Also scans for newly acquired tokens before refreshing balances To add blockchain accounts, see [Accounts](/usage-guides/portfolio/accounts). ### Manual Balances Displays manually tracked balances grouped by location (e.g., External, Blockchain, specific exchanges). These are useful for tracking assets that rotki can't query automatically, such as real estate, stocks, or assets on unsupported chains. See [Manual Balances](/usage-guides/portfolio/balances#manual-balances) for how to add them. ## Assets Table ![Dashboard Assets Table](/images/rotki_dashboard_assets.webp) The assets table shows all your holdings aggregated across all sources. Each row displays: | Column | Description | | ------------------ | -------------------------------------------------------------------- | | **Asset** | The asset name, symbol, and the chain it's on (for tokens) | | **Location** | Icons showing where the asset is held (blockchain, exchange, manual) | | **Price** | Current price in your profit currency | | **Amount** | Total quantity you hold | | **Value** | Total value in your profit currency | | **% of Net Value** | What percentage of your total portfolio this asset represents | ### Table Features * **Sorting** — Click any column header to sort. Default sort is by value (descending). * **Search** — Use the search box to filter by asset name or symbol. * **Pagination** — Configure how many rows to display per page using the "Rows per page" dropdown. * **Column Visibility** — Click the column configuration button to toggle optional columns ("% of Net Value" and "% of Group"). * **Row Expansion** — Click the expand arrow on a row to see a detailed breakdown of where that asset is held (per chain, per exchange, per protocol). * **Total Row** — A summary row at the bottom shows the aggregate value of all displayed assets. > \[!TIP] > If an asset shows a warning icon, it means the asset is not recognized by rotki's asset database. You can click the warning to navigate to the manual balance page for that asset. ## Liquidity Pools If you have assets in DeFi liquidity pools, a **Liquidity Pools** table appears below the assets table. It shows: * Pool name with icons for the constituent assets * Total value of your position * Percentage of net value Click the expand arrow to see the detailed asset composition of each pool. > \[!NOTE] > Some liquidity pool details are only available with a [premium subscription](/premium/). These are indicated by a lock icon. ## Liabilities If you have any tracked liabilities (debts), a **Liabilities** table appears with the same structure as the assets table, showing your outstanding obligations. ## NFT Balances If the NFT module is enabled, the **NFT Balances** table shows NFTs owned by your tracked accounts: * NFT name and collection * Price in the NFT's native asset * Estimated value in your profit currency * Percentage of your net value Click the link icon to navigate to the full [NFT balances](/usage-guides/portfolio/balances#nfts) page for more details on managing NFT prices and display settings. ## Refreshing Data Click **Refresh Prices** below the balance summary to update all asset prices from the configured [price oracles](/usage-guides/settings/blockchain#price-oracle-settings). To refresh balances from specific sources, use the refresh button on the individual balance summary columns (Exchange, Blockchain, or Manual). --- --- url: /premium/devices.md description: >- Managing devices connected to your rotki premium subscription and understanding per-tier device limits. --- # Device Management Manage devices using your rotki premium subscription and understand device limits for your plan tier. ## What are Device Limits? Each rotki premium tier includes a limit on how many devices can use the same rotki API credentials simultaneously. This prevents unauthorized sharing while allowing you to use rotki on multiple devices you own. Device limits vary by tier - check the [pricing page](https://rotki.com/pricing) for your tier's specific limit. ## Viewing Your Devices You can manage devices from two locations: **On the Website:** From the [devices list page](https://rotki.com/home/devices), you can see: * **Device name** - Identifier for each device * **Last active** - When the device last connected * **Registration date** - When the device was first added * **Current count** - How many devices are active * **Your limit** - Maximum allowed for your tier **In the App:** From **API Keys** → **rotki Premium**: * View all devices using your API credentials * See active device count vs. your limit * Identify which device you're currently using * Access device management options ![Premium devices management in the app](/images/premium_devices_app.png) ## Editing Device Names Device names help you identify which device is which (e.g., "Work Laptop", "Home Desktop", "MacBook Pro"). 1. Navigate to **API Keys** → **rotki Premium** in the sidebar of the App 2. Find the device to rename 3. Click the edit option 4. Enter a new name 5. Save changes ![Edit device name](/images/edit_device_name.png) ![Edit device name dialog](/images/edit_device_name_dialog.png) ::: tip Naming Strategy Use descriptive names to easily identify devices: * "MacBook Pro 2023" * "Home Desktop PC" * "Work Laptop" * "Linux Server" This makes it easier to identify and remove unused devices later. ::: ## Removing Devices ### Why Remove Devices Remove devices when: * You've reached your device limit and need to add a new device * You no longer use a particular device * You've replaced or sold a device * A device is showing but shouldn't be ### How to Remove Devices **On the Website:** 1. Go to the [devices list page](https://rotki.com/home/devices) 2. Find the device to remove 3. Click **Delete** or **Remove** 4. Confirm the deletion **In the App:** 1. Go to **Settings** → **Account** → **Premium Devices** 2. Find the device to remove 3. Click the remove/delete option 4. Confirm the action ::: warning Immediate Effect Removing a device takes effect immediately. If rotki is running on that device, it will lose premium access and may show authentication errors. ::: ## Device Limit Exceeded ### What Happens When You Exceed the Limit If you try to use rotki on a new device after reaching your limit: * Authentication will fail * You'll see an error message in the app * Premium features won't activate * The app may prompt you to manage devices ### What to Do When You Exceed the Limit To continue using rotki on a new device: **Option 1: Remove Unused Devices** 1. Identify devices you no longer use 2. Remove them from the website or another active device 3. Try authenticating again on the new device **Option 2: Upgrade Your Plan** If you genuinely need more devices: 1. Review higher tiers on the [pricing page](https://rotki.com/pricing) 2. Upgrade directly from your [subscription page](https://rotki.com/home/subscription) 3. See [Upgrading Your Subscription](/premium/plans-and-pricing#upgrading-your-subscription) for details ## Understanding Device Registration ### When is a Device Registered? A device is registered when you add rotki premium API credentials to the app and successfully authenticate with rotki servers. ### How Devices are Identified Devices are identified by: * Hardware identifiers * Operating system information * Installation instance ::: info Same Computer, Different Users Installing rotki multiple times on the same computer (e.g., different user accounts) may register as multiple devices, each counting toward your limit. ::: ### Device Registration Limits * Only successfully authenticated devices count toward your limit * Failed authentication attempts don't register devices * Removed devices immediately free up a slot ## Managing Multiple Devices ### Best Practices If you use rotki across multiple devices: 1. **Use descriptive names** - Make it easy to identify each device 2. **Regularly audit** - Remove devices you no longer use 3. **Plan ahead** - Consider your device needs when choosing a tier 4. **Keep track** - Know which devices are actively using your subscription ### Syncing Data Across Devices Device management is separate from data syncing. To sync your rotki data across devices: 1. Enable "Allow data sync with rotki Server" in each rotki instance 2. Use the same API credentials on all devices 3. See [Sync Data Guide](/usage-guides/#sync-data-with-rotki-server) for details ::: warning Don't Run Simultaneously Avoid running rotki on multiple devices at the same time to prevent data sync conflicts. ::: ## Checking Your Device Limit To see your tier's device limit: * Visit your [subscription page](https://rotki.com/home/subscription) to see your current tier and limits. * Check the [devices list page](https://rotki.com/home/devices) to view a list of all your current devices. * Navigate to **API Keys** → **rotki Premium** in the app to see your limit and a list of your current devices. ## Troubleshooting ### Device not showing in the list If a device should appear but doesn't: 1. Verify the device successfully authenticated (check in the app) 2. Refresh the devices page 3. Wait a few moments - registration may be processing 4. Check you're logged in to the correct rotki.com account ### Can't remove a device If you can't delete a device: 1. Ensure you have an active premium subscription 2. Try refreshing the page 3. Try removing from the app instead of the website (or vice versa) 4. Contact for assistance ### Device keeps re-appearing after removal If a removed device reappears: 1. Ensure rotki isn't still running on that device 2. If you still have access to the device, remove the API credentials from the app 3. The device will re-register if it's still trying to authenticate ### Wrong device count If the device count seems incorrect: 1. Remove and re-add API credentials in the app to force re-registration 2. Wait a few minutes for the count to update 3. Contact support if the issue persists ### Multiple entries for the same device If one physical device shows multiple entries: * This can happen if rotki was reinstalled or data was reset * Remove the duplicate/old entries * Keep only the active registration ## Security Considerations ### Unauthorized Devices If you see devices you don't recognize: 1. **Immediately** remove them from the devices list 2. Regenerate your API credentials from the [subscription page](https://rotki.com/home/subscription) by clicking **Regenerate** 3. Update your legitimate devices with the new credentials 4. Contact to report the issue See [API Keys & Secrets](/premium/api-keys#if-credentials-are-compromised) for security best practices. ### Regular Audits ::: tip Security Best Practice Periodically review your devices list (monthly or quarterly) to: * Ensure all listed devices are yours * Remove old devices you no longer use * Verify no unauthorized access has occurred ::: --- --- url: /requirement-and-installation/docker.md description: >- Run rotki in a Docker container, with configuration, Docker Compose templates, updating, and migrating data from the desktop app. --- # Docker & Self-Hosting rotki provides official Docker images starting from v1.11.0. Images are published on [DockerHub](https://hub.docker.com/r/rotki/rotki) as `rotki/rotki`. > \[!WARNING] > rotki was not designed to run over a public network. Keep the container inside a trusted environment (for example, on your home LAN or behind a VPN) and do not expose it directly to the internet to avoid unauthorized access to your data. > \[!NOTE] > Versions up to v1.13.2 report a dev version inside the app due to an old build process issue. This is cosmetic and doesn't affect functionality. ## Quick start Pull the latest image: ```sh docker pull rotki/rotki:latest ``` Start a container with persistent data and log volumes: ```sh docker run -d --name rotki \ -p 8084:80 \ -v $HOME/.rotki/data:/data \ -v $HOME/.rotki/logs:/logs \ rotki/rotki:latest ``` Open `http://localhost:8084` in your browser and you'll see the rotki login screen. If port `8084` is taken, pick any free port and change the left-hand side of `-p`. Your account data lives under `~/.rotki/data`; your logs are under `~/.rotki/logs`. Both survive container restarts and upgrades as long as you reuse the same volumes. > \[!WARNING] > On Linux, the mounted `data` and `logs` folders must be owned by `root` — that's the user the container runs as. If you change the owner, the container will hit permission errors and rotki will return 500 responses. ## Configuring the backend You can tune the backend with either a config file or environment variables. If both are present, the config file takes precedence. ### Config file Mount an extra volume for config: ```sh docker run -d --name rotki \ -p 8084:80 \ -v $HOME/.rotki/data:/data \ -v $HOME/.rotki/logs:/logs \ -v $HOME/.rotki/config:/config \ rotki/rotki:latest ``` Create `$HOME/.rotki/config/rotki_config.json`: ```json { "loglevel": "info", "logfromothermodules": true, "sleep-secs": 22, "max_size_in_mb_all_logs": 550, "max_logfiles_num": 3, "sqlite_instructions": 0 } ``` You can include only the options you want to override. Restart the container to apply changes. ### Environment variables ```sh docker run -d --name rotki \ -p 8084:80 \ -v $HOME/.rotki/data:/data \ -v $HOME/.rotki/logs:/logs \ -e LOGLEVEL=debug \ rotki/rotki:latest ``` Supported variables: `LOGLEVEL`, `LOGFROMOTHERMODULES`, `MAX_SIZE_IN_MB_ALL_LOGS`, `MAX_LOGFILES_NUM`, `SQLITE_INSTRUCTIONS`. Changing these requires recreating the container. ## Setting the timezone Set `TZ` when starting the container: ```sh docker run -d --name rotki \ -p 8084:80 \ -v $HOME/.rotki/data:/data \ -v $HOME/.rotki/logs:/logs \ -e TZ=America/New_York \ rotki/rotki:latest ``` See the [tz database list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for valid values. ## Updating to a newer version When a new rotki version is released: ```sh # 1. Stop and remove the old container (data lives in volumes, so this is safe) docker stop rotki docker rm rotki # 2. Pull the latest image docker pull rotki/rotki:latest # 3. Start a new container — reuse the same volumes docker run -d --name rotki \ -p 8084:80 \ -v $HOME/.rotki/data:/data \ -v $HOME/.rotki/logs:/logs \ rotki/rotki:latest ``` > \[!IMPORTANT] > Always reuse the same volumes. If you mount different ones, your existing accounts and data won't be visible to the new container. ## Docker Compose For most users, a simple private-network Compose file is the easiest way to keep rotki running. ### Private network **Using Docker-managed volumes:** ```yaml version: '3.7' services: rotki: environment: - TZ=America/Chicago image: rotki/rotki:latest ports: - '8084:80' networks: - rotki-net volumes: - rotki-data:/data - rotki-logs:/logs volumes: rotki-data: rotki-logs: networks: rotki-net: ``` **Using host paths:** ```yaml version: '3.7' services: rotki: environment: - TZ=America/Chicago image: rotki/rotki:latest ports: - '8084:80' networks: - rotki-net volumes: - $HOME/.rotki/data:/data - $HOME/.rotki/logs:/logs networks: rotki-net: ``` ### Public network with Traefik + basic auth > \[!WARNING] > Exposing rotki to the public internet is not recommended. If you do, protect it with at least basic authentication and TLS. This setup uses Traefik as a reverse proxy with basic auth and automatic Let's Encrypt TLS. Assuming you have a server at `rotki.example.com`: 1. Create a bcrypt-hashed password for the basic auth user: ```sh htpasswd -cB ~/.rotki/.htpasswd user ``` 2. Create `.env` next to `docker-compose.yml`: ```sh AUTH_USER=username FQDN=rotki.example.com LETSENCRYPT_EMAIL=user@example.com ``` 3. Create `docker-compose.yml`: ```yaml version: '3.11' services: proxy: image: traefik:2.9 restart: always command: - --global.sendAnonymousUsage=false - --providers.docker - --providers.docker.exposedByDefault=false - '--entrypoints.web.address=:80' - '--entrypoints.websecure.address=:443' - --certificatesresolvers.le.acme.httpchallenge=true - --certificatesresolvers.le.acme.httpchallenge.entrypoint=web - '--certificatesresolvers.le.acme.email=${LETSENCRYPT_EMAIL}' - --certificatesresolvers.le.acme.storage=/etc/acme/acme.json ports: - '80:80' - '443:443' networks: - rotki-net volumes: - $HOME/.rotki/.htpasswd:/auth/.htpasswd - $HOME/.rotki/acme/:/etc/acme/ - /var/run/docker.sock:/var/run/docker.sock:ro rotki: environment: - TZ=Europe/Berlin image: rotki/rotki:latest networks: - rotki-net volumes: - $HOME/.rotki/data:/data - $HOME/.rotki/logs:/logs labels: - traefik.enable=true - traefik.http.services.rotki.loadbalancer.server.port=80 - traefik.http.middlewares.redirect.redirectscheme.scheme=https - 'traefik.http.middlewares.rotki-auth.basicauth.realm=${AUTH_USER}' - traefik.http.middlewares.rotki-auth.basicauth.usersfile=/auth/.htpasswd - 'traefik.http.routers.rotki-insecure.rule=Host(`${FQDN}`)' - traefik.http.routers.rotki-insecure.middlewares=redirect - 'traefik.http.routers.rotki.rule=Host(`${FQDN}`)' - traefik.http.routers.rotki.middlewares=rotki-auth - traefik.http.routers.rotki.entrypoints=websecure - traefik.http.routers.rotki.tls.certresolver=le networks: rotki-net: ``` 4. Start it: ```sh docker-compose up -d ``` Visiting `http://rotki.example.com` will prompt for the basic auth user and password, then redirect to the rotki login page over HTTPS. This also makes rotki reachable from your mobile device. ### Watchtower for auto-updates Add a Watchtower service to the compose file above for zero-downtime updates (`--rolling-restart`): ```yaml watchtower: image: containrrr/watchtower command: - --label-enable - --interval - '60' - --rolling-restart volumes: - /var/run/docker.sock:/var/run/docker.sock ``` Then add this label to the `rotki` service so Watchtower manages it: ```yaml labels: - com.centurylinklabs.watchtower.enable=true ``` ## Moving accounts from the desktop app If you've been running rotki as a desktop app and want to switch to Docker, you can copy your account files into the Docker data volume. Find the desktop app's data directory using the [rotki data directory guide](/usage-guides/advanced/data-directory#rotki-data-directory), then copy any specific account over: ```sh # Example: Linux, user "alice", data volume at ~/.rotki/data sudo cp -R ~/.local/share/rotki/data/alice ~/.rotki/data/alice ``` The next time you start the Docker container, the `alice` account will appear on the login screen. ## Troubleshooting If you hit issues, check the logs at `$HOME/.rotki/logs/rotki.log` (or your custom logs volume) and [open an issue on GitHub](https://github.com/rotki/rotki/issues/new/choose) with the relevant lines. --- --- url: /contribution-guides/docker-publishing.md description: >- Manual steps for building and publishing multi-architecture rotki Docker images to Docker Hub. --- # Docker Publishing (Manual) If you need to publish on [hub.docker.com](https://hub.docker.com), follow these steps: > **Note:** Make sure you are logged in with an account that has access to publish to Docker. This process installs the qemu binaries required to build the `arm64` binary and uses buildx to build the images. Replace `REVISION` with the git SHA of the tag and `ROTKI_VERSION` with the tag name. ```sh docker pull tonistiigi/binfmt:latest docker run --rm --privileged tonistiigi/binfmt:latest --install arm64 docker buildx create --name imgbldr --use docker buildx inspect --bootstrap --builder imgbldr docker buildx build --build-arg REVISION='git sha' --build-arg ROTKI_VERSION=vx.x.x --file ./Dockerfile --platform linux/amd64 --platform linux/arm64 --tag rotki/rotki:vx.x.x --tag rotki/rotki:latest --push . ``` --- --- url: /requirement-and-installation/download.md description: >- Download and install rotki on Linux, macOS, or Windows using the official pre-built binaries. --- # Download & Install The easiest way to run rotki is to download a pre-built binary for your operating system from the [official releases page](https://github.com/rotki/rotki/releases/latest). Pick the package for your platform: * **Linux** — `rotki-linux_x86_64-*.AppImage` (or `.tar.xz`) * **macOS** — `rotki-darwin-*.dmg` (Intel or Apple Silicon) * **Windows** — `rotki-win32-*.exe` (installer) After installing, you can optionally [verify your download](/requirement-and-installation/verify) to confirm the binary is authentic. ## Linux ### AppImage Download the `linux-x64` AppImage from the [latest release](https://github.com/rotki/rotki/releases/latest) and make it executable: ```sh chmod +x rotki-linux_x86_64-vx.x.x.AppImage ``` Replace `vx.x.x` with the version you downloaded, then run the file to start rotki. ### Tarball Alternatively, download the `.tar.xz` archive and unpack it in a directory of your choice. The extracted folder contains a `rotki` executable — run it from the terminal to start rotki. ## macOS ### Homebrew The simplest option on macOS is Homebrew: ```sh brew install --cask rotki ``` ### Manual install Download the `darwin-x64` (Intel) or `darwin-arm64` (Apple Silicon) `.dmg` from the [latest release](https://github.com/rotki/rotki/releases/latest). Open the installer and drag the rotki icon into your **Applications** folder. You can then launch rotki from Launchpad or Finder. > \[!NOTE] > If macOS blocks the app the first time you open it, go to **System Settings → Privacy & Security** and allow rotki to run. See [this guide](https://ccm.net/faq/29619-mac-os-x-run-apps-downloaded-from-unknown-sources) for screenshots. ## Windows Download the `win32-x64` installer from the [latest release](https://github.com/rotki/rotki/releases/latest) and run it. Windows Defender or your antivirus may prompt you — the binary is signed by **Rotki Solutions GmbH**, which you can confirm by right-clicking the installer and checking its digital signature. ## First launch When rotki starts for the first time you'll see a sign-in/sign-up screen. From there you can create a local account and begin tracking your portfolio — see the [Quick Start Guide](/usage-guides/quick-start) for a step-by-step walkthrough. ## Troubleshooting If rotki fails to start or crashes during use, please [open an issue on GitHub](https://github.com/rotki/rotki/issues/new/choose) and include the log files found at: | OS | Log directory | | ------- | ------------------------------------------- | | Linux | `~/.config/rotki/logs/` | | macOS | `~/Library/Application Support/rotki/logs/` | | Windows | `%APPDATA%\rotki\logs\` | On Windows, you can also run the executable from the Command Prompt to capture startup errors printed to the console. ## See also * [Verify Your Download](/requirement-and-installation/verify) — confirm your binary is authentic * [Docker & Self-Hosting](/requirement-and-installation/docker) — run rotki in a container * [Build from Source](/requirement-and-installation/build-from-source) — for contributors and developers --- --- url: /usage-guides/tax-accounting/event-types.md description: >- Complete reference of all event types and subtypes in rotki with examples and default tax treatments. --- # Event Types and Subtypes Reference This page provides a complete reference for all event types and subtypes in rotki. Understanding these categories is essential for reviewing your transaction history and ensuring your PnL reports are accurate. ## How event types work Every transaction in rotki is categorized with two fields: * **Event Type**: The broad category of what happened (e.g., Trade, Deposit, Spend) * **Event Subtype**: The specific action within that category (e.g., Fee, Reward, Airdrop) Together, these determine how rotki treats the event in accounting — whether it's taxable, whether it counts as an acquisition or a spend, and how it affects your cost basis. Not every combination of type and subtype is valid. The table in [all valid type/subtype combinations](#all-valid-type-subtype-combinations) below lists every combination that rotki recognizes. ## Event Types ### Trade A trade is an exchange of one asset for another. In rotki, trades are represented as a pair of events with consecutive `sequence_index` values: * First event: `Trade` type with `Spend` subtype (what you gave up) * Second event: `Trade` type with `Receive` subtype (what you got) **Example**: Swapping 1 ETH for 2000 USDC on Uniswap. **Default tax treatment**: Taxable (Swap accounting treatment). The spend side triggers a cost basis calculation. The receive side is an acquisition at the current market value. **When to use**: Any swap, trade, or exchange of one asset for another — whether on a CEX, a DEX, or OTC. | Subtype | UI Category | Direction | Example | | --------- | ------------- | --------- | -------------------------- | | `Spend` | swap | Out | Sending 1 ETH in a swap | | `Receive` | swap | In | Getting 2000 USDC in swap | | `None` | informational | Neutral | Informational trade event | | `Fee` | fee | Out | Trading fee on an exchange | ### Multi-Trade Similar to Trade but used when a single transaction involves multiple assets being swapped (e.g., aggregator routes through multiple pools). | Subtype | UI Category | Direction | Example | | --------- | ----------- | --------- | --------------------------------- | | `Spend` | swap | Out | Outgoing side of a multi-hop swap | | `Receive` | swap | In | Incoming side of a multi-hop swap | | `Fee` | fee | Out | Fee on a multi-asset swap | ### Deposit Moving assets into an exchange, wallet, or protocol. | Subtype | UI Category | Direction | Example | | --------------------- | ---------------- | --------- | -------------------------------------- | | `Deposit Asset` | account deposit | Neutral | Depositing ETH to Kraken | | `Deposit For Wrapped` | deposit | Out | Depositing DAI to receive cDAI | | `Deposit To Protocol` | protocol deposit | Neutral | Depositing into Aave lending pool | | `Bridge` | bridge | Out | Sending ETH to the Arbitrum bridge | | `Place Order` | deposit | Out | Placing a limit order (e.g., CoW Swap) | | `Fee` | fee | Out | Fee on a deposit | ### Withdrawal Moving assets out of an exchange, wallet, or protocol. | Subtype | UI Category | Direction | Example | | ------------------------ | ------------------- | --------- | -------------------------------------- | | `Remove Asset` | account withdraw | Neutral | Withdrawing BTC from Binance | | `Redeem Wrapped` | withdraw | In | Redeeming cDAI back to DAI | | `Withdraw From Protocol` | protocol withdrawal | Neutral | Withdrawing from Aave lending pool | | `Bridge` | bridge | In | Receiving ETH from the Optimism bridge | | `Cancel Order` | cancel order | In | Cancelling a CoW Swap order | | `Refund` | refund | In | Getting refunded from a failed order | | `Generate Debt` | borrow | In | Borrowing from a lending protocol | | `Fee` | fee | Out | Fee on a withdrawal | ### Spend A plain expenditure — you spent crypto and received nothing (or something non-crypto) in return. | Subtype | UI Category | Direction | Example | Notes | | ---------------- | ----------- | --------- | -------------------------------------- | ---------------------------------- | | `None` | send | Out | Paying for a service with BTC | Taxable (loss) | | `Fee` | fee | Out | Paying gas fees on Ethereum | Depends on "EVM Gas Costs" setting | | `Return Wrapped` | return | Out | Returning aDAI to Aave to get DAI back | Not taxable (protocol interaction) | | `Payback Debt` | repay | Out | Repaying a loan on Aave | | | `Donate` | donate | Out | Donating crypto to a cause | | | `Payment` | pay | Out | Making a payment | | | `Clawback` | clawback | Out | Assets clawed back by protocol | | | `Burn` | burn | Out | Burning tokens | | ### Receive You received assets — this is an acquisition event. | Subtype | UI Category | Direction | Example | Notes | | ----------------- | ------------------ | --------- | -------------------------------------------- | --------------------------- | | `None` | receive | In | Receiving a payment in crypto | Taxable (income) | | `Reward` | claim reward | In | Receiving CRV rewards from Curve | Taxable (income) | | `Airdrop` | airdrop | In | Receiving a governance token airdrop | Taxable (income) | | `Receive Wrapped` | receive | In | Getting aDAI after depositing DAI to Aave | Not taxable (receipt token) | | `Return Wrapped` | receive | In | Getting back wrapped tokens | | | `Generate Debt` | borrow | In | Borrowing assets from a lending protocol | | | `Donate` | receive donation | In | Receiving a donation | | | `Liquidate` | liquidation reward | In | Receiving assets from liquidating a position | | | `Payment` | receive payment | In | Receiving a payment | | | `Grant` | receive grant | In | Receiving a grant (e.g., Gitcoin) | | | `Interest` | receive interest | In | Receiving interest from a lending protocol | | | `Cashback` | cashback | In | Receiving cashback rewards | | | `Refund` | refund | In | Getting a refund | | | `Spam` | spam | In | Spam/phishing tokens sent to your address | Ignored in accounting | ### Transfer Moving assets between your own accounts. Not taxable. | Subtype | UI Category | Direction | Example | | -------- | ----------- | --------- | ------------------------------------- | | `None` | transfer | Neutral | Moving ETH from one wallet to another | | `Donate` | donate | Out | Donating via a transfer | | `Fee` | fee | Out | Fee on a transfer | **When to use**: If rotki categorized a self-transfer as a spend or trade, change it to `Transfer` with subtype `None` to avoid it being counted as taxable. ### Staking Events related to staking assets. | Subtype | UI Category | Direction | Example | Notes | | --------------------- | -------------- | --------- | ---------------------------------------- | -------------------------------------------- | | `Deposit Asset` | stake | Out | Staking ETH in the Eth2 deposit contract | | | `Deposit For Wrapped` | stake | Out | Staking and receiving a receipt token | | | `Remove Asset` | unstake | In | Unstaking and getting assets back | | | `Redeem Wrapped` | unstake | In | Redeeming staked receipt tokens | | | `Reward` | staking reward | In | ETH2 consensus layer rewards | Depends on "Omit ETH Staking Events" setting | | `Block Production` | new block | In | ETH block production reward | | | `MEV Reward` | mev | In | MEV reward from block building | | | `Fee` | fee | Out | Fee related to staking | | ### Migration (Migrate) Moving assets from one version of a protocol to another, where you don't gain or lose value. | Subtype | UI Category | Direction | Example | | --------- | ----------- | --------- | ------------------------------------ | | `Spend` | migrate | Out | Sending SAI in a SAI→DAI migration | | `Receive` | migrate | In | Receiving DAI in a SAI→DAI migration | **When to use**: Protocol upgrades or token migrations where the economic value doesn't change. Both events should have type `Migrate`, with the outgoing side as `Spend` and the incoming side as `Receive`. ### Loss Events where you lost assets involuntarily. | Subtype | UI Category | Direction | Example | | -------------------------- | ------------------------ | --------- | ----------------------------------- | | `None` | loss | Out | General loss of assets | | `Liquidate` | liquidation loss | Out | Getting liquidated on a loan | | `Hack` | hack | Out | Losing assets in a protocol exploit | | `Liquidity Provision Loss` | liquidity provision loss | Out | Impermanent loss realized on exit | ### Informational Events that contain useful information but have no financial impact. | Subtype | UI Category | Direction | Example | | ------------------ | ------------- | --------- | ------------------------------------- | | `None` | informational | Neutral | General informational event | | `Governance` | governance | Neutral | Casting a governance vote | | `Deposit Asset` | informational | Neutral | Informational deposit event | | `Remove Asset` | withdraw | In | Informational withdrawal event | | `Place Order` | place order | Neutral | Order placement notification | | `Create` | new project | Neutral | Creating a Maker vault or Gnosis Safe | | `Update` | update | Neutral | Updating a protocol position | | `Apply` | apply | Neutral | Applying for something on-chain | | `Approve` | approval | Neutral | Token approval (spending allowance) | | `Attest` | attest | Neutral | On-chain attestation (e.g., EAS) | | `MEV Reward` | mev | In | MEV reward info | | `Block Production` | new block | In | Block production info | | `Consolidate` | combine | Neutral | Consolidating positions | | `Delegate` | delegate | Neutral | Delegating voting power | | `Message` | message | Neutral | On-chain message | ### Renew Renewal of a subscription or recurring service payment. | Subtype | UI Category | Direction | Example | | ------- | ----------- | --------- | -------------------------------- | | `None` | renew | Out | Paying for an ENS domain renewal | ### Deploy Deploying a smart contract. | Subtype | UI Category | Direction | Example | | ------- | ----------------- | --------- | --------------------------- | | `None` | deploy | Neutral | Deploying a smart contract | | `Spend` | deploy with spend | Out | Deploying with an ETH spend | | `NFT` | mint nft | In | Deploying/minting an NFT | ### Mint Minting tokens or NFTs. | Subtype | UI Category | Direction | Example | | ------- | ----------- | --------- | -------------- | | `NFT` | mint nft | In | Minting an NFT | | `Fee` | fee | Out | Minting fee | ### Burn Burning tokens or NFTs. | Subtype | UI Category | Direction | Example | | ------- | ----------- | --------- | -------------- | | `NFT` | burn | Out | Burning an NFT | ### Fail A failed transaction (you still pay gas). | Subtype | UI Category | Direction | Example | | ------- | ----------- | --------- | --------------------------------- | | `Fee` | failed | Out | Gas fee from a failed transaction | ### Adjustment Forced adjustments by a system like a centralized exchange (e.g., exchange delisting a token and converting it). | Subtype | UI Category | Direction | Example | | --------- | ----------- | --------- | ------------------------------------ | | `Spend` | send | Out | Asset removed by exchange adjustment | | `Receive` | receive | In | Asset received from adjustment | ### Margin Margin trading events. | Subtype | UI Category | Direction | Example | | -------- | ----------- | --------- | ------------------------ | | `Profit` | profit | In | Profit from margin trade | | `Loss` | loss | Out | Loss from margin trade | | `Fee` | fee | Out | Margin trading fee | ### Transaction to Self A transaction where you sent assets to yourself (same address). | Subtype | UI Category | Direction | Example | | ------- | ---------------- | --------- | ------------------------------- | | `None` | self transaction | Neutral | Sending ETH to your own address | ### Exchange Adjustment Adjustments made by exchanges to your balance. | Subtype | UI Category | Direction | Example | | --------- | ----------- | --------- | ----------------------------- | | `Spend` | send | Out | Exchange debits your balance | | `Receive` | receive | In | Exchange credits your balance | ### Exchange Transfer Transfers associated with exchange deposits/withdrawals that have both an on-chain and exchange side. | Subtype | UI Category | Direction | Example | | --------- | ---------------- | --------- | --------------------------------------- | | `Spend` | account withdraw | Neutral | On-chain side of an exchange withdrawal | | `Receive` | account deposit | Neutral | On-chain side of an exchange deposit | | `Fee` | fee | Out | Fee on the transfer | ## All valid type/subtype combinations The following table lists every valid combination of event type and subtype recognized by rotki. Combinations not listed here are not valid. | Event Type | Valid Subtypes | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Trade | Spend, Receive, None, Fee | | Staking | Deposit Asset, Deposit For Wrapped, Reward, Remove Asset, Redeem Wrapped, Block Production, MEV Reward, Fee | | Deposit | Deposit Asset, Deposit For Wrapped, Deposit To Protocol, Bridge, Place Order, Fee | | Withdrawal | Remove Asset, Redeem Wrapped, Withdraw From Protocol, Bridge, Cancel Order, Refund, Generate Debt, Fee | | Transfer | Donate, None, Fee | | Spend | Return Wrapped, Payback Debt, Fee, Donate, Payment, None, Clawback, Burn | | Receive | Reward, Receive Wrapped, Generate Debt, Return Wrapped, Airdrop, Donate, None, Liquidate, Payment, Grant, Interest, Cashback, Refund, Spam | | Adjustment | Spend, Receive | | Informational | None, Governance, Deposit Asset, Remove Asset, Place Order, Create, Update, Apply, Approve, Attest, MEV Reward, Block Production, Consolidate, Delegate, Message | | Migrate | Spend, Receive | | Renew | None | | Deploy | None, Spend, NFT | | Fail | Fee | | Loss | Liquidate, Hack, Liquidity Provision Loss, None | | Mint | NFT, Fee | | Burn | NFT | | Multi Trade | Spend, Receive, Fee | | Margin | Profit, Loss, Fee | | Transaction To Self | None | | Exchange Adjustment | Spend, Receive | | Exchange Transfer | Spend, Receive, Fee | ## Quick reference: common customizations | Situation | Event Type | Event Subtype | | ---------------------------------------- | --------------- | -------------------------- | | Swap / trade on DEX or CEX | `Trade` | `Spend` + `Receive` (pair) | | Moving assets to an exchange | `Deposit` | `Deposit Asset` | | Moving assets from an exchange | `Withdrawal` | `Remove Asset` | | Depositing into DeFi (get receipt token) | `Deposit` | `Deposit For Wrapped` | | Depositing into DeFi (no receipt token) | `Deposit` | `Deposit To Protocol` | | Withdrawing from DeFi (return receipt) | `Withdrawal` | `Redeem Wrapped` | | Withdrawing from DeFi (no receipt) | `Withdrawal` | `Withdraw From Protocol` | | Receiving wrapped/receipt tokens | `Receive` | `Receive Wrapped` | | Returning wrapped/receipt tokens | `Spend` | `Return Wrapped` | | Sending assets across a bridge | `Deposit` | `Bridge` | | Receiving assets from a bridge | `Withdrawal` | `Bridge` | | Transfer between own wallets | `Transfer` | `None` | | Paying gas fees | `Spend` | `Fee` | | Receiving staking rewards | `Staking` | `Reward` | | Claiming DeFi rewards | `Receive` | `Reward` | | Receiving an airdrop | `Receive` | `Airdrop` | | Paying for a service | `Spend` | `None` | | Getting paid in crypto | `Receive` | `None` | | Borrowing from a protocol | `Withdrawal` | `Generate Debt` | | Repaying a loan | `Spend` | `Payback Debt` | | Token migration (old→new) | `Migrate` | `Spend` + `Receive` (pair) | | ENS renewal, subscription | `Renew` | `None` | | Token approval, governance vote | `Informational` | `Approve` / `Governance` | | Lost in hack / exploit | `Loss` | `Hack` | | Liquidation (your position) | `Loss` | `Liquidate` | | Failed transaction (gas only) | `Fail` | `Fee` | ## Entry types In addition to event type/subtype, rotki distinguishes between different **entry types** based on the source of the event: | Entry Type | Description | | ------------------------ | --------------------------------------------------------------------------------------------- | | **History Event** | Generic events from any source (exchanges, manual input, CSV import) | | **EVM Event** | Decoded on-chain events from EVM chains (Ethereum, Optimism, Polygon, Arbitrum, Base, Gnosis) | | **EVM Swap Event** | A specialized EVM event for swaps, supporting multiple spend/receive assets | | **ETH Withdrawal Event** | ETH consensus layer withdrawal | | **ETH Block Event** | ETH block production reward | | **ETH Deposit Event** | ETH2 staking deposit | | **Asset Movement Event** | Exchange deposit or withdrawal | | **Swap Event** | A trade/swap from non-EVM sources | The entry type determines which fields are available when editing an event. For example, EVM events have a `Counterparty` field (the protocol or address you interacted with), while generic history events do not. ## Editing events If an event is miscategorized, you can edit it directly from the History Events page. See the [common customization guide](/usage-guides/history/events#common-customization) for step-by-step instructions and examples. Changes you make to event types/subtypes directly affect how they are processed in the PnL report. --- --- url: /usage-guides/integrations/exchange-keys.md description: >- Connecting centralized exchanges to rotki via API keys, with per-exchange setup instructions. --- # Exchange API Keys This page covers connecting centralized exchanges to rotki via read-only API keys. Go to the `API Keys` menu in the sidebar, then **Exchanges**. ## Exchanges API Keys ![List of connected exchanges](/images/rotki_add_exchange_2.png) You can integrate many different exchanges with rotki via API Keys. Currently supported exchanges are: * Kraken (Spot and Future) * Poloniex * Binance * Bitmex * Coinbase * Coinbase Prime * Gemini * Bitstamp * Binance US * Bitfinex * Bitcoin.de * Iconomi * KuCoin * Independent Reserve * Bitpanda * OKX * Woo * Bybit * HTX * Crypto.com (experimental) ![Add API keys for a new exchange](/images/rotki_add_exchange_1.png) ### Steps to Add Exchange API Key: 1. Create API key on your exchange (see [API key permissions](#api-key-permissions)) 2. Navigate to `API Keys > Exchanges` in the left sidebar 3. Click button `Add an exchange` to open addition menu 4. Enter your: * API Key * API Secret (for the majority of exchanges) * Password (for some exchanges) 5. Click `Save` ### After Adding: * Successful addition: Exchange will appear in your list * If failed: * Verify key and secret are correct * Some exchanges may have issues due to timestamp difference between the computer and the server (e.g. binance, read [this](https://github.com/tiagosiebler/awesome-crypto-examples/wiki/Timestamp-for-this-request-is-outside-of-the-recvWindow)) ### Sync Settings: * Option to enable/disable exchange synchronization * Consider disabling to avoid IP bans from frequent syncs > **Note**: At the moment, [margin trades](https://github.com/rotki/rotki/issues/1980) and [future trades](https://github.com/rotki/rotki/issues/1606) are not yet supported in rotki. ### API key permissions rotki only needs read-only permissions for your accounts. As a general rule, exchanges (e.g., Binance) group all the read-only permissions as "read" or "view". ![Simple API key permissions](/images/add_exchange_api_keys_binance.png) In the case of an exchange providing a more granular permissions scheme (e.g., Coinbase, Kraken) or having additional options (e.g., query limits, passphrase), refer to the exchange documentation or get in touch via their customer support channel. ![Granular API key permissions](/images/add_exchange_api_keys_coinbase.png) You may also try creating an API key with the minimum read-related permissions, then adding it in rotki and finally checking that the connection was successful and data was loaded as expected. Otherwise, try again adding more read-related permissions. #### Kraken When inputting the API key for Kraken, you need to specify the type of your Kraken account, which depends on your Kraken account verification level. Refer to [this](https://support.kraken.com/hc/en-us/articles/360001395743-Verification-levels-explained) for more information. ![Kraken account type](/images/exchanges_add_kraken.png) To track your Kraken Futures balances, you can optionally provide your Futures API key and Futures API secret in the same Kraken exchange form. Both fields must be provided together. When set, rotki will query your Kraken Futures cash, margin, and flex balances and merge them into your overall Kraken balance total. #### Binance / Binance US To improve the speed of querying trade information using the Binance API, you can specify which market pairs to query instead of querying all possible pairs. This reduces the number of requests made to Binance servers, avoiding potential rate limits and failures. To select specific markets, edit your Binance exchange instance configuration. ![Edit Binance in the exchanges section](/images/exchanges_edit_binance.png) ##### Market Pairs (required) Choose the markets in the `Filter market pair(s)` search. ::: warning **Due to Binance API limitations**, querying trade information does not work without specifying market pairs. Binance's endpoint requires every possible market pair to be queried individually, and their rate limits make it impossible to query all markets for your entire history. This API issue has existed for years and has not been fixed by Binance. You must select which specific markets you want to query for the integration to work properly. ::: ![Binance markets selection](/images/binance_markets_selection.png) Once finished, click on save. #### Coinbase Prime Coinbase Prime requires an API Key, API Secret, and a Passphrase. Make sure you provide all three when adding the exchange. #### OKX OKX requires an API Key, API Secret, and a Passphrase. When adding OKX, you also need to select your **region**: * **Global** — the default OKX platform. * **EEA** — for European Economic Area users. * **US** — for United States users. Make sure to select the region that matches the OKX platform you registered on, as the API endpoints differ between regions. #### Crypto.com Crypto.com is currently listed as an **experimental** exchange. It requires an API Key and API Secret. Since it is experimental, some functionality may be incomplete or subject to change. --- --- url: /usage-guides/integrations/external-services.md description: >- Configuring external service API keys such as Etherscan, CryptoCompare, and other data providers. --- # External Services ## Why External API Keys Are Needed Required for accessing: * Historical crypto prices * EVM transactions * Other external data services ## How to Add External API Keys: 1. Create free account on service website 2. Generate API key 3. In rotki: * Go to `API Keys → External Services` * Enter your API key(s) ![External services](/images/external_services.png) ## Etherscan We **strongly recommend** getting an Etherscan API Key - it's completely free and will make the queries much faster! Without it, the queries will be really slow. You just need to: 1. Create an account at [here](https://etherscan.io/register) 2. Generate a free API Key 3. Add the key to rotki. You only need one Etherscan API key for all EVM chains since the key is now unified. ## Blockscout Blockscout is an open-source blockchain explorer that rotki can use as an alternative data source for on-chain transactions and token transfers. You can add per-chain API keys, allowing rotki to query Blockscout instances for specific EVM chains. This can be useful as a fallback or supplement to Etherscan. ## Helius Helius is a Solana indexer and RPC provider. Adding a Helius API key allows rotki to query Solana transaction data more reliably and with higher rate limits. You can get an API key from [helius.dev](https://www.helius.dev/). ## CryptoCompare CryptoCompare provides historical cryptocurrency price data. While rotki can use CryptoCompare without an API key, adding one increases the rate limits for price queries. You can get a free API key from [cryptocompare.com](https://www.cryptocompare.com/cryptopian/api-keys). ## Beaconchain Beaconchain provides Ethereum consensus layer (beacon chain) data. Adding an API key allows rotki to query validator information with higher rate limits. You can get an API key from [beaconcha.in](https://beaconcha.in/user/settings#api). ## OpenSea OpenSea is an NFT marketplace and data provider. Adding an OpenSea API key allows rotki to fetch NFT data such as collection information and valuations. You can request an API key from [opensea.io](https://docs.opensea.io/reference/api-keys). ## Alchemy Alchemy is a multi-chain data provider and price oracle. rotki can use Alchemy for blockchain data queries and as an additional price source. Adding an API key improves rate limits and reliability. You can get a free API key from [alchemy.com](https://www.alchemy.com/). ## Loopring balances To have your Loopring balances detected, you will need an API Key from Loopring. To get one, visit [Loopring Security](https://loopring.io/#/layer2/security) and unlock your account. In the list of options, click on **Export Account**. ![Get Loopring keys](/images/get_loopring_keys.png) Then in rotki, you need to add the API key in the `Loopring` section. After following these steps, your balances in the dashboard will be updated including the Loopring information. ![Loopring balances in the UI](/images/loopring_balances.png) ## Monerium You can integrate Monerium with rotki to import your transaction data. This feature is only available for premium users. As long as you provide Monerium credentials, all Monerium transactions on Mainnet, Polygon, and Gnosis chain will be decorated with bank data (or chain bridging data), which you can also see in the Monerium app. 1. For bank transfers from/to your address, you will be able to see the destination/source IBAN along with the memo of the transfer. 2. For automatic EURe bridging between EVM chains, you will see amounts, from/to EVM chains along with from/to address. ![Monerium decorated transactions](/images/monerium_transactions.png) ### Adding Monerium OAuth Token ![Monerium get access token](/images/monerium_get_access_token.png) ![Monerium OAuth](/images/monerium_oauth.png) To connect your Monerium account: 1. **Get Access Token:** * In rotki, navigate to `API Keys → External Services → Monerium`. * Click the **Get access token** button. 2. **Complete OAuth Flow:** * You will be redirected to rotki.com to connect via Monerium OAuth. * Follow the authentication flow on the Monerium OAuth page. 3. **Return to rotki:** * **Standard mode**: You will be automatically redirected back to the app after completing the OAuth flow. * **Docker mode**: You will need to manually copy the access token and refresh token from the OAuth page and input them into rotki. 4. **Redecode Transactions:** * After successfully adding your Monerium credentials, you need to redecode the Monerium transactions in the history events section to see the updated bank data. See [Redecoding blockchain transactions](/usage-guides/history/events#redecoding-blockchain-transactions) for more information on how to redecode transactions. > **Note**: The Monerium credentials only provide read-only access to your Monerium data. When you authenticate, Monerium's OAuth consent screen may show that rotki is requesting broad permissions. This is because Monerium's API doesn't currently support granular permission scopes, so all OAuth tokens appear to request full access. However, rotki only performs read-only operations and cannot modify your account, initiate transfers, or make changes to your Monerium data. The OAuth authentication flow described above is mandated by Monerium's API requirements, not a design choice by rotki. rotki simply integrates with their authentication system as required. ## Gnosis Pay ![Gnosis Pay SIWE](/images/gnosis_pay_siwe.png) You can integrate Gnosis Pay with rotki to import your transaction data. This feature is only available for premium users. ### Adding Gnosis Pay Access Token To connect your Gnosis Pay account: 1. **Connect Wallet:** * In rotki, navigate to `API Keys → External Services → Gnosis Pay`. * Click the **Sign in with Ethereum** button. * Connect the wallet that controls the Safe wallet of your Gnosis Pay account. 2. **Sign Message:** * Sign the message to authenticate and get the access token. 3. **Redecode Transactions:** * After successfully connecting your Gnosis Pay account, you need to redecode the Gnosis Pay transactions in the history events section to enrich the transaction details. See [Redecoding blockchain transactions](/usage-guides/history/events#redecoding-blockchain-transactions) for more information on how to redecode transactions. > **Note**: The access token only provides read-only access to your Gnosis Pay data. The "Sign in with Ethereum" authentication process described above is mandated by Gnosis Pay's API requirements, not a design choice by rotki. rotki simply integrates with their authentication system as required. ## The Graph rotki uses The Graph to obtain Balancer balances and particular ENS data. You can create one [here](https://thegraph.com/studio/apikeys). ![Create The Graph API key](/images/create_the_graph_api_key.png) After creating the API key, you can add it to rotki. Additionally, ensure that the generated API key is authorized for the Balancer and ENS subgraphs. ![The Graph subgraphs](/images/the_graph_subgraphs.png) ## DefiLlama rotki integrates with DefiLlama for price data. An API key is not required, but a paid API key will provide higher rate limits. You can find more information about their API [here](https://defillama.com/pro-api). ## CoinGecko rotki uses CoinGecko for cryptocurrency data. An API key is not required, but a paid API key will provide higher rate limits. You can find more information about their API [here](https://www.coingecko.com/en/api). --- --- url: /contribution-guides/feature-requests.md description: How to submit feature requests for rotki using the GitHub issue template. --- # Feature Requests Use the [feature request](https://github.com/rotki/rotki/issues/new?template=feature_request.md) template. Describe exactly what it is that you would like to see added to rotki and why that would provide additional value. Please note that feature requests are just that. Requests. There is no guarantee that they will be worked on in the near future. --- --- url: /faq.md description: >- Frequently asked questions about rotki, premium subscriptions, supported exchanges, and common issues. --- # Frequently Asked Questions ## Questions on the application ### What is rotki? rotki is an open-source portfolio tracking, analytics, and tax reporting application that respects your privacy. It is focused on crypto assets but will also slowly facilitate tracking of more traditional assets. ### Why should I use it? Unlike virtually every other service out there which offers you the ability to track crypto assets, get analytics, and generate tax reports, rotki is a local application. And its basic version is also free. A local application allows you to **own your data**. You don't need to give your API keys, or any of your financial history to a centralized third party. We strongly advise against using any such centralized services. Your data is not safe with them. ### What does it offer me? rotki offers tracking of all your crypto assets no matter where they are. Either on a blockchain or on one of the supported exchanges. You can also manually input information on your Fiat assets (i.e., how much EUR, USD, etc. you own) so that the analytics also take them into account. Manual input of actions that you did and would like to be tracked is also possible by adding an "external trade". It also allows you to get a tax report, essentially calculating all trades in a given period and determining your profit or loss depending on your given settings. For more details on what is offered and how to use it check the [Usage Guide](/usage-guides/). ### Will it remain free to use? rotki's base version will always remain open-source and free to use. It's on GitHub and even if the current maintainer stops developing for whatever reason, anyone can pick it up and continue. ## Questions on Premium ### What is rotki Premium? rotki is an open-source and free application. In order to fund development, we also have a paid tier which offers more features and for which many new awesome features will be developed. If you like rotki, you can support us with a premium subscription and you not only get to fund open-source but also get additional features. To get a rotki subscription register on [our website](https://rotki.com/products). There you can also see what exactly is offered in premium. ### Is there a lifetime premium plan? Short answer: **No** At rotki, we believe in building sustainable, long-term software that delivers continuous value to our users. Offering a lifetime subscription may sound appealing on the surface, but in reality, it's a model that often leads to the collapse of the very products it's meant to support. Many companies that adopt this approach either shut down within a few years or abandon the product once the initial influx of revenue dries up. rotki has been around since 2017, delivering continuous, original improvements every month. Offering a lifetime subscription would require us to put a fixed price on the indefinite future work of our entire team, which is simply not realistic or fair. Building and maintaining a privacy-respecting, local-first, open-source financial tool involves real and growing costs. It's also worth noting that our current pricing model hasn't changed since 2017. We're currently re-evaluating it to better reflect the actual cost of development, support, and infrastructure, especially in light of inflation and the expanded scope of what rotki offers today. Our goal is to keep rotki accessible while ensuring its long-term health and independence. ### How do I manage my premium subscription? You can manage your premium subscription, payment methods, devices, and referrals through your rotki.com account. See the [Premium documentation](/premium/) for detailed guides on: * [Managing your subscription](/premium/subscription) - View payment history, cancel subscription * [Payment methods](/premium/payment-methods) - Add, remove, or change cards * [Device management](/premium/devices) - Manage device limits * [Referral program](/premium/referrals) - Create and share referral codes ### How do device limits work? Each premium tier has a device limit. You can manage your devices from the app (**Settings → Account → Premium Devices**) or from the [website](https://rotki.com/home/devices). If you exceed your device limit, remove unused devices to continue using rotki. See [Device Management](/premium/devices) for more information. ### Need help with premium? If you have questions about premium subscriptions, payment, billing, or account management: * Check the answers above in this FAQ section * Visit the [Premium documentation](/premium/) for detailed guides * Contact support at * Join our [Discord community](https://discord.rotki.com) ## Questions on Roadmap and Features ### How can I see what's planned for rotki? Please take a look at the GitHub issues [here](https://github.com/rotki/rotki/issues). For more specific planning check the GitHub [milestones](https://github.com/rotki/rotki/milestones). ### Why doesn't rotki support exchange X/Y/Z or have feature X/Y/Z? rotki is open-source software and we welcome Pull Requests. If you would like something to be done about a feature request, you can create an issue on GitHub or do it yourself. Questions are welcome in our [Discord](https://discord.rotki.com). ## Miscellaneous Questions ### Where does the name come from? rotki is an abbreviation for Rotkehlchen. That is the German word for the bird known in English as the [European Robin](https://en.wikipedia.org/wiki/European_robin). For pronunciation check [here](https://upload.wikimedia.org/wikipedia/commons/4/42/De-Rotkehlchen2.ogg). ## Common Issues ### My asset is not showing in rotki If your asset is not showing in rotki, even though you are sure that you have a balance, you need to first ensure that the asset is present on the list of assets (read [inspecting list of assets](/usage-guides/data-management/assets#inspecting-list-of-assets)). If you still cannot find your asset, it might be ignored. By default, rotki only displays un-ignored assets in the table. To also show the ignored assets, choose the `Filter by ignored status → Show all`, and then unignore the asset manually. Additionally, you can whitelist the asset to prevent it from being automatically ignored by rotki's spam detection (read: [whitelisting of ignored assets](/usage-guides/data-management/assets#whitelisting-of-ignored-assets)). After whitelisting the token, you may need to re-detect it to see it in your balances (read: [token detection methods](/usage-guides/data-management/assets#whitelisting-and-re-detecting-missing-tokens)). If the asset is still not showing, you may need to add it manually. ### My transaction is not showing in rotki If a transaction is not showing in rotki, it may be due to an ignored asset being part of the transaction. To view transactions with ignored assets, enable `Show entries with ignored assets`, and if your transaction is now visible, check which assets used in the transaction are ignored and then un-ignore them manually. For more information on un-ignoring and optionally whitelisting assets, see [My asset is not showing in rotki](/faq#my-asset-is-not-showing-in-rotki) above. ### Events are missing If you notice that some events are missing for a chain or from exchanges, you can re-pull events for a specific time range. See [Re-pulling events missed in the past](/usage-guides/history/events#re-pulling-events-missed-in-the-past) for detailed instructions. ### My balances are not showing after importing my history/creating history events It's not a bug. At the moment, we don't use events to determine current holdings. Balances are only calculated from connected exchanges, connected blockchain addresses, and manual balances. ### Restoring backed up database at new account creation fails Please, make sure you are using your premium subscription API keys/secret and the same password. ### Data with multiple accounts/devices is not synced Please, make sure all your accounts have the "Allow data sync with rotki Server" switched on, and that on each log-in you make the appropriate choice when prompted to replace the local database. See the section [Sync data with rotki server](/usage-guides/#sync-data-with-rotki-server) for more information about how to sync data with multiple accounts/devices. ### ENS data not updating for newly registered name/address combination If you just registered your ENS name and you don't see the name and/or avatar being properly displayed in rotki, then that means that the value is cached and you need to force a refresh. You can do that by going to `Accounts → EVM Accounts` view and pressing the refresh button on the top. ### Issues related to PnL report generation You can go to [PnL report creation problems](/usage-guides/history/pnl#pnl-report-creation-problems) ### I receive a notification error: `can't deserialize XXX, unknown asset YY found` The most common reason for this issue is that when you moved your user database to a new computer (either by doing it manually or using premium sync), you forgot to move the `global database` from your old computer. The global database contains some important data, including your assets (especially custom ones), so it also needs to be moved. Important to remember that the global DB is not moved by the premium sync mechanism. You can follow the instructions here to manually move the global database: [manually move global database](/usage-guides/#manually-move-global-database). If you are affected by this, there are a number of things you can do. * For assets that are EVM tokens with identifiers like `eip155:10/erc20:0x99C59ACeBFEF3BBFB7129DC90D1a11DB0E91187f` if you press [redecode all history events](/usage-guides/history/events#redecoding-blockchain-transactions) then the redecoding process should repopulate them in the global db. * If you have an asset with a unique identifier that looks like `a19964d9-20da-a6dc-1b50-9f293eb85c0d` then that means it's a custom asset or a manually input asset and we have no idea what it is. To figure out you would need to [access the database manually](/usage-guides/advanced/database-access) and query the event or trade that had it. For example for trades: ```sql SELECT * from trades WHERE base_asset='a19964d9-20da-a6dc-1b50-9f293eb85c0d' OR quote_asset='a19964d9-20da-a6dc-1b50-9f293eb85c0d'; ``` Or for history events: ```sql SELECT * from history_events WHERE asset='a19964d9-20da-a6dc-1b50-9f293eb85c0d'; ``` Then, from the response, understand which asset it is, recreate it, and merge it with the old identifier following the merging process outlined [here](/usage-guides/data-management/assets#merging-two-assets) ### Out of gas error during eth\_call If you see an error like the following: ```log [17/12/2020 18:31:29 CET] WARNING rotkehlchen.chain.ethereum.manager: Failed to query own node for > due to Error doing call on contract 0x06FE76B2f432fdfEcAEf1a7d4f6C3d41B5861672: {'code': -32000, 'message': 'out of gas'} ``` while rotki is querying your local geth node for something, then it means that the query has hit the gas limit cap. You can fix this by simply adding the `--rpc.gascap 0` argument to your geth node. This will have an unlimited gas cap. Be careful if it's a node exposed to the public as this may allow a malicious `eth_call` to crash your node. ### Local system clock is not synchronized Your local system clock must be synchronized with certain remote servers, such as exchanges. If your clock is not synchronized, requests to these servers will fail. rotki will either display a specific error message (e.g., a 409 status code indicating a local system clock synchronization issue) or a generic 500 error message (please, report it to us). To resolve this issue, follow the official guidelines provided by your operating system on how to synchronize your clock with an Internet Time Server. You can find detailed instructions for fixing this problem on Windows, Mac, and Linux in this link: [Fixing Clock Synchronization](https://github.com/tiagosiebler/awesome-crypto-examples/wiki/Timestamp-for-this-request-is-outside-of-the-recvWindow). Once synchronized, try the request again. --- --- url: /usage-guides/settings/general.md description: >- Configuring general app settings including profit currency, analytics, CSV export, and NFT display options. --- # General Settings This section provides information on how to customize the application through the settings. Click on the user icon on the top right and choose "Settings" to access basic customization options. ## Profit Currency rotki calculates everything, including your total profit/loss during the PnL report, in a given fiat currency, called the `profit_currency`. By default, this is USD. You can change this by clicking on the currency icon in the top right menu and selecting your preferred currency. ![Changing the profit currency](/images/sc_profit_currency.png) ## Application Settings Access the settings menu via `User icon → Settings`. ## General Settings ![Customizing the general app settings](/images/sc_general_settings.png) #### Anonymous Usage Analytics Specify whether the application can submit anonymous usage analytics. This helps measure active users while ensuring data is anonymized and contains no sensitive information. #### Auto detect tokens Specify whether to automatically detect tokens and refresh balances by periodically checking historical events. #### Display Date in Localtime Specify whether dates in CSV exports should be displayed in local time rather than UTC. Enabled by default. #### CSV Export Specify your preferred date format and delimiter for CSV exports. #### Automatic database sync Whether to force push when a size discrepancy occurs during automatic db sync. #### Version update check Set how often (in hours) the version will be checked for updates. #### Balance Snapshots Saving Frequency Set how often (in hours) the balance data snapshots are saved. This data helps calculate statistics historical and graph data for the user. #### BTC Derivation Gap Limit Set the derivation gap limit for deriving addresses from a bitcoin xpub. More information [here](https://insights.blockonomics.co/bitcoin-what-is-this-gap-limit/). #### Date Format Set the date display and date input format in the rotki user interface, such as `%m/%d/%Y %H:%M:%S` for month/day/year hour:minutes:seconds. Check [here](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes) for valid formats. ### Amount Settings ![Customizing the app's amount settings](/images/sc_amount_settings.png) #### Main Currency Same as [changing the profit currency](#profit-currency). #### Floating Precision Set the number of decimal points shown in the UI for floating point numbers. #### Thousands Separator Set the symbol separating every 3 digits for large numbers, e.g., `1,000,000`. #### Decimal Separator Set the symbol separating the floating part of a number, e.g., `5.42`. ### Subscript Format Whether to apply subscript formatting for consecutive zeros after the decimal point in small numbers, e.g., `0.000000087` => `0.0₇87`. #### Amount Rounding Choose the rounding mechanism: `Round up`, `Round down`, or `Half even`. Customize how amounts and values are rounded. #### Abbreviation for large numbers If enabled, large numbers will be abbreviated, e.g., `1,234,567` as `1.23 M`. Set the minimum value to be abbreviated. #### Currency Location Set whether the currency symbol appears before or after the number, e.g., `$1,000` or `1,000$`. ### NFT Settings ![Customizing the app's NFT settings](/images/sc_nf_settings.png) #### Include NFTs in Graphs and Total Amounts Decide whether to include NFTs in total net worth calculations and displayed graphs. #### NFT Images Rendering Setting For privacy, allow images from all or specific domains. More details [here](https://medium.com/@alxlpsc/critical-privacy-vulnerability-getting-exposed-by-metamask-693c63c2ce94). ### History Event Settings Configure settings related to history event processing and management. #### Auto Create Profit Events Automatically create virtual profit/loss events when processing history. This setting controls whether rotki generates profit and loss events during history processing. #### Internal Transaction Conflict Repull Configure how rotki handles internal transaction conflicts. You can set the number of transactions to repull per batch and the frequency (in minutes) at which the system automatically attempts to repull conflicting internal transactions. #### Skipped External Events View and manage events that were skipped during external event processing. This section shows a summary of skipped events grouped by location. You can export the skipped events to CSV or attempt to reprocess them. ### External Service Settings Configure retry and timeout behavior for external service calls made by rotki. #### Query Retry Limit The number of times to retry a query to external services before giving up. Default is 5. #### Connect Timeout The number of seconds to wait before giving up on establishing a connection to an external service. Default is 30 seconds. #### Read Timeout The number of seconds to wait for the first byte after a connection to an external service has been established. Default is 30 seconds. #### Suppress Missing API Key Notifications Select services for which you do not want to receive notifications about missing API keys. Supported services include Etherscan, Beaconchain, The Graph, and Helius. ### Backend Settings ![Customizing the backend settings](/images/usage_guides_settings_general_backend_settings.webp) #### Log Level Specify the minimum severity level for recorded log messages. You can change this at runtime without restarting rotki. This is useful for temporarily enabling debug logs when troubleshooting issues, without needing to modify the [`rotki_config.json`](/usage-guides/advanced/backend-config.html) file or restart the application. Additional log-related settings such as max log size, max number of log files, and logging from other modules can be configured from the [login screen backend settings](/usage-guides/settings/account#advanced-backend-settings). --- --- url: /usage-guides/utilities/help.md description: >- Accessing help resources, reporting bugs, and submitting feature requests through the in-app support menu. --- # Help & Support To access the Help & Support menu, click the **?** icon in the toolbar. ![Help & Support Menu](/images/help_support_menu.png) The Help & Support menu provides quick access to: * **[Report Issue](#report-issue)** - Report bugs or request features * **Usage Guide** - Get started with the documentation * **FAQ** - Common questions about the application * **Discord** - Join the community and get support * **Github** - Review the code and open issues * **Twitter / X** - Follow for updates ## Report Issue If you encounter a bug or want to request a new feature, click on **Report Issue** to open the issue submission form. ![Report Issue Dialog](/images/report_issue_dialog.png) ### Filling Out the Form 1. **Title** - Enter a brief summary of the issue (up to 100 characters) 2. **Description** - Provide detailed information about the bug or feature request (up to 1500 characters) ### Submission Options You can submit your issue through one of the following channels: * **GitHub** - Opens an issue on the rotki GitHub repository * **Google Form** - Submit via a form for private matters * **Email** - Send directly to the team ::: tip GitHub issues are publicly visible. For private matters, use Google Form or Email instead. ::: ### Tips #### Need Immediate Help? Get quick help from the community in the **#support** channel on [Discord](https://discord.rotki.com), or you can DM the team directly. #### Taking Screenshots? Before taking screenshots, enable privacy or scramble mode to hide sensitive data like balances and addresses. You can find this option in the privacy settings. --- --- url: /usage-guides/history/events.md description: >- Browsing, filtering, decoding, and editing historical events from exchanges and blockchains. --- # History events > \[!TIP] > **Trying to understand event types?** See the [Event Types & Subtypes Reference](/usage-guides/tax-accounting/event-types) for a complete guide to what each event category means, with examples and default tax treatments. rotki is capable of pulling and decoding a bunch of different events, ranging from EVM chain transactions to exchanges events and more. When you visit the `History Events` section the process to obtain all the information will start. You will be able to check the status in an informative breakdown per blockchain address. Free users are limited to a number of latest events. ## Supported events Currently, these events are detected automatically by rotki: * Transactions from registered **EVM accounts** (except Avalanche). * Transactions from registered **Bitcoin** and **Bitcoin Cash** accounts. * Transactions from registered **Solana** accounts. * Events from registered exchanges. * ETH withdrawal events * ETH block events * ETH deposit events * Asset movement events (deposits and withdrawals). * Swap events (trades). Additionally, you can add your custom events. ## Events filtering History events can be filtered with these advanced filters. The filters will persist, meaning if you go to another page or log out, the last filter will still be applied when you open the history events page. * Accounts (tracked blockchain / exchange accounts) * Time range * Asset involved in the transaction * Protocol that interacted in the transaction * Location of the event (ethereum, optimism, kraken, etc.) * Event type (deposit, withdrawal, etc.) * Event subtype (fee, spend, etc.) * Entry type (EVM event, ETH block event, etc.) * Counterparty address * Tx hash/signature of a particular transaction that you want to check * Index of an eth2 validator that you want to see events for * Show only customized events * Show entries with ignored assets * Should match exact filter (whether to only show the events that match the filter, excluding the other events in the same group) ## Refreshing Events You can choose to refresh all events by clicking the main `Refresh` button, or you can open the menu and choose to refresh only certain types of events or accounts. ### By Chain Refreshes specific chains, optionally limited to only specific accounts on those chains. ![Refreshing onchain events](/images/refreshing_onchain_events.png) To see the status, you can click the button here: ![See query status](/images/see_query_status.png) Basically, what happens when you refresh the transactions/events is: 1. It will query the transactions from the "last queried time" to the current time. 2. For EVM events, after rotki queries these new transactions, it will try to decode them. 3. The events will be displayed correctly in the UI only after they are properly decoded. ![Events query status](/images/events_query_status.png) ### Exchange Events Refreshes the events from specific exchanges. ![Refreshing exchange events](/images/refreshing_exchange_events.png) ### ETH Staking Events Refreshes ETH withdrawals and block production events. ![Refreshing eth staking events](/images/refreshing_eth_staking_events.png) ### Protocol Events Refreshes events from specific protocols such as Monerium and Gnosis Pay, pulling data from the protocol's API to enrich the existing onchain events. ![Refreshing protocols events](/images/refreshing_protocols_events.png) ## Redecoding blockchain transactions Sometimes you may need to redecode events for blockchain transactions (EVM and Solana). ### Redecode a single transaction 1. Click the three-dots `⋮` menu on the transaction row 2. Click `Redecode events` This will re-read and re-decode the transaction's events and try to understand what happened. If the transaction contains custom events, you will get an extra confirmation asking whether to also reset these custom events. ![Redecode events for a transaction](/images/redecode_events.png) ::: tip Advanced: Redecode with options If you need more control, use `Redecode with options` (button at the right of `Redecode events`) to: * Select how custom events should be handled by the redecoding logic * Choose the priority for indexers that we want to use when re-querying remote information about the transaction ::: ### Redecode all queried transactions To redecode all transactions that have been queried, click `Redecode All Transactions` at the top of the page. ![Menu to redecode all queried EVM transactions events](/images/redecode_all_events.png) ### Transaction decoding status To see the status of event decoding, click the menu button and go to `Transaction Decoding Status`. ![Menu to redecode events for an EVM transaction](/images/redecode_events_status_button.png) You will see the status of the EVM events redecoding. ![EVM events redecoding breakdown](/images/redecode_events_status.png) ### Notes EVM transactions and events can be deleted, but to restore them you will have to either purge all transactions or add by the transaction hash. ![History events query status](/images/events_filter.png) ## Export history events as CSV Events can be exported as CSV, click on `Export CSV` button and accept prompt to download exported events. ![Button to download events as csv](/images/events_csv_export.png) ## Delete transactions & events ![Menu to delete EVM transactions events](/images/delete_transaction_events.png) ## Add transaction by hash ![Add transaction by hash](/images/add_tx_by_hash.png) If you want to add a transaction that was either deleted or for some reason missed, or was not found by rotki, you can add it by transaction hash by clicking the menu as seen in the picture. ## Re-Pulling events missed in the past It is possible that due to network issues, RPC errors, or other problems, some events may have been missed during the initial sync. This can happen when: * An RPC node provided broken information. * Etherscan or other indexers had wrong data. * Sources used were not fully synced. * Other kind of bugs. You can find the menu by clicking the three-dots `⋮` menu in the top right and selecting `Re-pulling Events`. You can pull blockchain transaction events and events that come from exchanges. ![Repull transactions](/images/repull_transactions.png) If any missed transactions are found, you'll see a notification indicating how many new transactions were discovered. You can click the action in the notification to view the pulled transactions. ![Repulled transactions result](/images/repull_transactions_notification.png) After the transactions are pulled, blockchain transactions need to be decoded, while events from exchanges will appear directly. For blockchain transactions, you can either: * Wait a few moments for automatic decoding * Click the refresh button to trigger decoding manually * Check the transaction decoding status to monitor progress Once decoded, the blockchain transactions will appear in the history view with all their associated events. ## Missing accounting rule If you see this warning button, it means the event won't be processed correctly in accounting. It could be due to improper decoding or a missing accounting rule for that event. You can fix it by editing the event or adding the missing accounting rule. You can also edit the events if they have special meaning to you, such as OTC trades or transfers between accounts. ![The button indicates that the event won't be processed correctly.](/images/event_not_processed.png) ## Edit accounting rule ![Edit accounting rule](/images/edit_accounting_rule.png) You can customize how events are processed in accounting by editing their accounting rules. When editing an accounting rule, you have two options: 1. **Apply to all matching events** - Updates all existing events that share the same combination of event type, subtype, and counterparty. This creates a general rule that affects all similar events. 2. **Apply to this specific event only** - Creates a special accounting rule that targets only the selected event, without affecting other similar events. ## Ignore events in accounting By default, all events will be processed in accounting, but you can ignore unwanted events, so they won't be processed. You can click on the three-dots `⋮` menu to display the options for the group of events, and click `Ignore events in accounting`/`Unignore events in accounting`. ## Select multiple events You can go to selection mode and select multiple events by clicking this menu in the top left: ![Selection mode](/images/selection_mode.png) You can perform two actions: 1. Delete the selected events 2. Set regular accounting rules for specific events * Note: Multiple selected events must have the same entry type/subtype combination to apply custom accounting rules. ![Select multiple events](/images/select_multiple_events.png) ## Add / edit events There are 10 types of events in rotki: :::tabs \== History Event ![History event form](/images/events_history_event_form.png) Here the non obvious fields are: * `Event Type`: We have created a categorization of all the actions in a set of major event types. This field will describe the action category. * `Event Subtype`: Inside an event type you can perform different actions. This subtype will let you describe exactly what is happening in the event. * `Sequence Index`: Is an internal index that sets the order in which events happened in the transactions. This allows knowing how events are sorted and should be taken into account. By default it corresponds to the event log index in the blockchain with a few exceptions. \== EVM Event ![EVM event form](/images/events_evm_event_form.png) Currently we support EVM events for these chains: * Ethereum * Optimism * Polygon PoS * Arbitrum One * Base * Gnosis * Scroll * Binance Smart Chain * ZkSync Lite Here the non obvious fields are: * `Event Type`: We have created a categorization of all the actions in a set of major event types. This field will describe the action category. * `Event Subtype`: Inside an event type you can perform different actions. This subtype will let you describe exactly what is happening in the event. * `Sequence Index`: Is an internal index that sets the order in which events happened in the transactions. This allows knowing how events are sorted and should be taken into account. By default it corresponds to the event log index in the blockchain with a few exceptions. * `Location Label`: This is the address related to the event, for example if you are receiving one asset in a transfer or calling a contract will match with your address. * `Address`: Registered rotki account which this event is linked to. * `Counterparty`: This is the other part of the transaction, the address you are interacting with. Can be a protocol identifier if the transaction is decoded as part of a protocol. \== EVM Swap Event ![EVM swap event form](/images/events_evm_swap_event_form.png) Basically it's similar to `EVM Event`, but it's specifically for swap events. You can add multiple `spend` and `receive` assets. \== ETH Withdrawal Event ![ETH withdrawal event form](/images/events_eth_withdrawal_event_form.png) \== ETH Block Event ![ETH block event form](/images/events_eth_block_event_form.png) \== ETH Deposit Event ![ETH deposit event form](/images/events_eth_deposit_event_form.png) \== Asset Movement Event ![Asset movement event form](/images/events_asset_movement_form.png) \== Swap Event ![Swap event form](/images/events_swap_event_form.png) \== Solana Event Similar to an EVM Event but for the Solana blockchain. The location is fixed to Solana. Key fields include: * `Signature`: The Solana transaction signature (equivalent to a transaction hash). * `Event Type` / `Event Subtype`: Same categorization as other event types. * `Sequence Index`: Order of the event within the transaction. * `Counterparty`: The protocol or address you interacted with. * `Address`: The Solana address related to the event. Advanced options include `Group Identifier` and `Extra Data` for additional context. \== Solana Swap Event Similar to the EVM Swap Event but for the Solana blockchain. The location is fixed to Solana. You can add multiple `spend` and `receive` assets, along with optional fee entries. Key fields include: * `Signature`: The Solana transaction signature. * `Spend` / `Receive`: Lists of assets spent and received in the swap, each with an asset and amount. * `Fee`: Optional fee entries that can be enabled via the fee checkbox. * `Address`: The Solana program or contract address involved. * `Sequence Index` / `Counterparty`: Same as other event types. ::: For history event, and EVM history event, if any event was not decoded the way you expected it to be, you can always customize events using the settings described above or file a bug report via the in-app Report Issue dialog (Help & Support > Report Issue), on our github repository, or in our discord server. The customizations that you make also affect how events are processed in accounting. ### Common customization These are some common customizations you may want to do, based on the issue: * `Event Type` to `Transfer` if you are sending money to a friend / (another account you own) and don't want the event to be taxable. The `Event Subtype` should be `None` in that case. * `Event Type` to `Deposit` / `Withdrawal` if you're moving assets between exchanges or wallets. Use `Event Subtype` of `Deposit Asset` / `Remove Asset`. These won't be taxable in P\&L reports and ensure balance tracking is accurate. * `Event Type` to `Deposit` / `Withdrawal` with `Event Subtype` of `Deposit To Protocol` / `Withdraw From Protocol` if assets are going to or coming from a DeFi protocol (staking, lending, etc.) without receiving wrapped tokens. These won't be taxable in P\&L reports and ensure balance tracking is accurate. * `Event Type` to `Withdrawal` and `Event Subtype` to `Bridge` if you are receiving something from another chain via some kind of bridge. And `Event Type` to `Deposit` and `Event Subtype` to `Bridge` if you are depositing to a bridge in order to move something to another chain. * For a swap: The first event should be `Event Type`: `Trade` and `Event Subtype`: `Spend`, while the second event should be `Event Type`: `Trade` and `Event Subtype`: `Receive`. But in swaps what's also important is the `sequence_index`. They need to be subsequent and the send should come before the receive. * `Event Type` to `Spend` / `Receive` and `Event Subtype` to `None` if it is a plain expenditure / receipt. * `Event Type` to `Receive` and `Event Subtype` to `Reward` if you got a reward for something. * `Event Type` to `Receive` and `Event Subtype` to `Airdrop` if you received an airdrop. * `Event Type` to `Receive` / `Spend` and `Event Subtype` to `Receive Wrapped` / `Return Wrapped` accordingly if you interacted with a protocol (e.g. Curve, Yearn, Aave, etc.) and received wrapped / returned some wrapped tokens. * `Event Type` to `Spend` and `Event Subtype` to `Fee` if you are paying a fee for some of your actions. * `Event Type` to `Migration` if it is a migration of assets from one protocol to another and you don't lose / gain anything from this event. For example when migrating from SAI to DAI. There is two events in a migration. Both should have type `Migration` and the OUT event should have `Event Subtype` set to `Spend`, while the IN event should have `Event Subtype` set to `Receive`. * `Event Type` to `Staking` and `Event Subtype` to `Deposit Asset` if it is a staking deposit event. For example staking in eth2 or in liquity. * `Event Type` to `Renew` and `Event Subtype` to `None` if it is a renewal of any subscription or service that you are paying for. * `Event Type` to `Informational` and `Event Subtype` to `None` if the event contains some useful information but it shouldn't be considered in accounting at all. Events that have been modified will appear marked in the UI. ![Customized events in the UI](/images/customized_events.png) ## Resolving Issues rotki can detect certain issues with your history events that may affect accounting accuracy. When issues are found, you will see a warning button with a badge showing the total number of issues at the top of the History Events page. ![Issue check button](/images/history_events_issue_check_button.png) Clicking the button opens a menu where you can check for specific types of issues. Currently, rotki detects the following: ### Unmatched Asset Movements ::: warning Premium Feature Asset movement matching is only available for certain premium subscription tiers. Visit the [pricing page](https://rotki.com/pricing) for details on which tiers include this feature. ::: An unmatched asset movement is an exchange deposit or withdrawal that hasn't been linked to its corresponding on-chain blockchain transaction. For example: * You **withdraw** from an exchange, but there is no matching **receive** event on a tracked blockchain address. * You **deposit** to an exchange, but there is no matching **send** event from a tracked blockchain address. This can happen when: * The blockchain address involved is not tracked in rotki. * The corresponding on-chain event was missed or not yet synced. * There's a significant time or amount difference between the exchange record and the on-chain event. * The exchange doesn't provide enough information (such as the blockchain or transaction hash) to automatically link the movement to the corresponding on-chain event, even if that event already exists in your history. #### How to resolve ![Match asset movements dialog](/images/history_events_unmatched_asset_movements.png) You have several options to resolve unmatched asset movements: 1. **Auto Match** - Click the `Trigger automatic matching` button to let rotki automatically match movements with corresponding on-chain events based on amount, asset, and timestamp. You can configure the amount tolerance and time range settings before triggering auto match. 2. **Find Match** (manual) - Click `Find Match` on a specific movement to search for potential matches. You can adjust the search criteria: * **Time range** (in hours) - Maximum allowed time difference between the movement and the on-chain event. * **Amount tolerance** (in %) - Maximum allowed percentage difference between the movement amount and the on-chain event amount. * **Only show same assets** - Filter results to the same asset. Potential matches are displayed in a list, with **recommended** matches highlighted. Select one or more matching events and click `Confirm Match`. A single asset movement can be linked to multiple on-chain events, which is useful when the on-chain side was split across multiple transactions. ![Potential matches dialog](/images/history_events_unmatched_asset_movements_potential.png) 3. **Ignore** - If a movement has no corresponding on-chain event (e.g., fiat currency deposits/withdrawals), click `Ignore` to mark it as having no match. Ignored movements are moved to the **Ignored** tab and can be restored later. 4. **Ignore All Fiat** - Quickly ignore all fiat currency movements at once, since fiat movements don't have blockchain transactions. > \[!TIP] > You can pin the matching dialog to the side of the History Events page, allowing you to browse events while working on matches side-by-side. ### Duplicate Custom Events Duplicate custom events occur when you have customized (manually edited) a blockchain event, and a non-customized version of the same event also exists. This typically happens when: * A transaction is re-decoded after you had already customized one of its events, creating both the original decoded event and your customized version. * Events are re-pulled, generating new events alongside your existing customized ones. Duplicates can cause incorrect accounting since the same action may be counted more than once. rotki categorizes duplicates into two types: * **Auto-fixable** - The customized and non-customized events are exact matches (only differing by sequence index). These can be safely auto-fixed. * **Manual review** - The events share the same asset and direction but have other differences. These require manual inspection before resolving. When duplicates are detected, an alert banner will appear showing the count for each category, with a `View` button to navigate to the affected events. ![Duplicate custom events alert](/images/history_events_duplicate_custom_events.png) #### How to resolve 1. **Auto Fix All** - For auto-fixable duplicates, click `Auto Fix All` to remove all the duplicate non-customized events at once, keeping your customized versions. 2. **Individual Fix** - Click the `Fix` button on a specific duplicate event to remove just that one duplicate. 3. **Manual review** - For duplicates that need manual review, click `View` to see the affected events in the history view. Inspect the events and manually resolve them by editing or deleting the incorrect one. ![Duplicate events in history view](/images/history_events_duplicate_custom_events_view.png) ### Internal Transaction Conflicts Internal transaction conflicts occur when rotki detects inconsistencies in internal (trace-level) EVM transactions. These can arise from issues such as: * **All zero gas** - All internal transactions in the trace have zero gas values, which typically indicates incomplete or corrupt data from the data source. These conflicts trigger a **repull** from the data source. * **Duplicate exact rows** - Multiple identical internal transaction entries exist for the same transaction. These conflicts trigger a **fix & redecode** to remove duplicates and re-process the transaction. * **Mixed zero gas** - Some internal transactions in the trace have zero gas while others don't, indicating partial data corruption. These conflicts trigger a **fix & redecode**. * **Mixed zero gas & duplicate** - Both zero gas and duplicate conditions are present in the same transaction. > \[!NOTE] > This feature was introduced in v1.42.1 as a one-time remediation for internal transaction data issues. The conflicts table is temporary and will be removed in a future release once all conflicts have been resolved. When conflicts are detected, a banner will appear in the History Events page alerting you to the number of conflicts that need attention. ![Internal transaction conflicts banner](/images/internal_tx_conflicts_banner.webp) You can also access the conflicts dialog from the three-dot `⋮` menu at the top right of the History Events page by clicking `Check internal tx conflicts`. An orange dot indicator will appear when there are pending conflicts. ![Internal transaction conflicts menu](/images/internal_tx_conflicts_menu.webp) Click `Review` in the banner or `Check internal tx conflicts` in the menu to open the Internal Transaction Conflicts dialog, which shows all detected conflicts organized into three tabs: * **Pending** - Conflicts that haven't been resolved yet. * **Failed** - Conflicts where the automatic resolution attempt failed. * **Fixed** - Conflicts that have been successfully resolved. ![Internal transaction conflicts dialog](/images/internal_tx_conflicts_dialog.webp) Each conflict shows the transaction hash, chain, action type (repull or fix & redecode), timestamp, reason, last retry time, and any error from the last attempt. You can filter the list by chain or date range using the combined filters. #### How to resolve 1. **Resolve individually** - Click the refresh button on a specific conflict to trigger resolution for that transaction. 2. **Resolve in bulk** - Select multiple conflicts using the checkboxes and click `Resolve Selected` to process them all at once. A progress indicator will show the current status, and you can cancel the operation at any time. 3. **Automatic resolution** - rotki will periodically attempt to resolve pending conflicts in the background. Conflicts that have never been retried are prioritized first, followed by those with the oldest retry timestamps. You can configure how often and how many conflicts are processed per run (see [Settings](#internal-transaction-conflict-settings) below). > \[!TIP] > If you have manually customized any history events for a conflicting transaction, your edits are preserved. For fix & redecode conflicts, redecoding is skipped on customized transactions to protect your changes. #### Failed conflicts When a conflict resolution attempt fails (e.g., the data source is temporarily unavailable or returns an error), the conflict is moved to the **Failed** tab. This tab shows all conflicts where the last resolution attempt was unsuccessful, along with the error message from the last attempt. ![Internal transaction conflicts failed tab](/images/internal_tx_conflicts_dialog_failed.webp) You can retry failed conflicts at any time by selecting them and clicking `Resolve Selected`, or by clicking the refresh button on individual entries. The automatic resolution system will also periodically retry failed conflicts. #### Pinning to sidebar You can pin the conflicts panel to the side of the History Events page by clicking the pin icon in the dialog header. This allows you to browse your history events while keeping the conflicts list visible for reference. ![Internal transaction conflicts pinned sidebar](/images/internal_tx_conflicts_pinned.webp) #### Show in history events Click the external link icon on a conflict to highlight the corresponding transaction in the History Events view. If the panel is not already pinned, this will automatically pin it, allowing you to browse conflicts and events side-by-side. #### Internal transaction conflict settings You can configure the automatic conflict resolution behavior by clicking the gear icon in the dialog header. ![Internal transaction conflicts settings](/images/internal_tx_conflicts_dialog_settings.webp) Two settings are available: * **Transactions per batch** - The number of conflicts to process per periodic task run (default: 20, minimum: 1). * **Repull frequency (minutes)** - How often the system automatically attempts to resolve conflicts (default: 60 minutes, minimum: 0.5 minutes). These settings are also available in `Settings > General > History Events`. ![Internal transaction conflicts in general settings](/images/internal_tx_conflicts_general_settings.webp) --- --- url: /usage-guides/history/import-data.md description: >- Importing trade and transaction data from CSV files exported by exchanges into rotki. --- # Import CSV Go to `Import Data` menu in the sidebar. ## Import exchange data (CSV) For exchanges that don't support integration through API keys (or haven't integrated to rotki), you can still import your trades or transactions. ![Import CSV Data](/images/sc_data_import.png) ### Steps to Import CSV Files: 1. Export CSV from your exchange 2. In rotki: * Navigate to `Import Data` * Select your CSV file ### Date Format Settings: If time format doesn't match rotki's default: 1. Enable `Use custom date format to parse your file` 2. Specify your CSV's time format ### Import Process: * Select data source * Click "Import Data" in left sidebar * Follow provided instructions ### Cointracking.info rotki can import any trade CSV data exported from [cointracking.info](https://cointracking.info/). But in general, it's not recommended to utilize cointracking as their exported data are missing a lot of information. ### Binance.com rotki can import a CSV data file exported from [binance.com](https://binance.com/). But due to Binance's CSV format, some data may not be importable. You will see warnings if this happens. By importing a CSV file, you can import more than with the API. Particularly: Trades, Deposits and Withdrawals, Small assets exchange BNB, ETH 2.0 Staking and ETH 2.0 Staking Rewards, Launchpool Interests, POS savings interest, POS savings purchase, POS savings redemption. ### BitMEX.com rotki can import a CSV data file exported from [BitMex](https://bitmex.com/). You may see warnings if data can't be imported. If this happens, please reach out to us on Discord or open an issue on GitHub. ### Bitstamp.net rotki can import a CSV data file exported from [Bitstamp](https://www.bitstamp.net/). You may see warnings if data can't be imported. If this happens, please reach out to us on Discord or open an issue on GitHub. ### Bittrex [Bittrex](https://bittrexglobal.com/) is a now bankrupt exchange and as such you probably can use this only if you had exported the files while it was running. rotki can import trades, deposit/withdrawals from the different bittrex CSVs. ### Bisq You can import data from [Bisq](https://bisq.network/) into rotki. All trades from Bisq can be picked up by the given CSV. ### Block.fi [BlockFi](https://en.wikipedia.org/wiki/BlockFi) is a now bankrupt exchange and as such you probably can use this only if you had exported the files while it was running. rotki can import two different CSV files from BlockFi. One for the trades and one for all other transactions. ### Blockpit rotki can import trades and other activity data from [Blockpit](https://www.blockpit.io/)'s CSV files. ### Bitcoin.tax You can import trades, income and spending CSV files from [Bitcoin.tax](https://bitcoin.tax/). ### Crypto.com mobile You can import data from [crypto.com](https://crypto.com/) mobile app into rotki. Note that this concerns only the Crypto.com mobile application. If you want to connect your Crypto.com Exchange account, please wait until we support it and then connect to it as an exchange. ### Kucoin rotki can import the trades CSV file from [Kucoin](https://www.kucoin.com/). ### Nexo rotki can import the transactions CSV file from [Nexo](https://nexo.com/). ### ShapeShift.com You can import trade CSV data file exported from [ShapeShift](https://shapeshift.com/). Transactions will come from adding your Blockchain Accounts used with ShapeShift to rotki. Import data in the same section as the image above in the prior heading. When exporting trades from ShapeShift, the selected wallet may show DEX trades in the user interface. If it is not the Native wallet, DEX trades may not show up in the user interface, but they still export to CSV. This importer ignores DEX trades, as they are covered by premium support for Uniswap and SushiSwap. ### Uphold.com You can import transaction history CSV data exported from the [Uphold](https://uphold.com/) activity page. Transactions will be created when the row's origin currency and destination currency are the same. Trades will be created if the currencies differ and a rate will be determined automatically. ## rotki Generic Import You can import data (trades & events) from exchanges not supported by rotki by clicking "Import Data" on the left sidebar, selecting `Custom Import` and following the prompt. This involves the user converting the source (a not directly supported exchange, protocol, etc.) data to match the import format of rotki. > **Note**: Keep in mind that all assets that you enter are identified by their asset identifier and not the symbol, as symbols are not unique. The identifier differs per asset and at the moment for ERC20 tokens follows the [CAIP-19](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-19.md) format, and for others, it's just the asset symbol or a random string for manually input tokens. For the CAIP-19 format, it's essentially calculated by knowing the chain ID and the address of your token. So for mainnet (chain ID 1) and USDT (0xdAC17F958D2ee523a2206206994597C13D831ec7), it's `eip155:1/erc20:0xdAC17F958D2ee523a2206206994597C13D831ec7`. You can easily find the identifier of each asset by going to `Manage Assets > Assets` section and copying the identifier of the asset in question. The import is split into two types: ### rotki Generic Trades Import This is solely for importing generic trades. The expected file format is **CSV** with the following headers and descriptions as a guide: 1. **Location**: This is the source of the data. It should be one of rotki's [supported locations](#supported-locations). If it is not supported, use `"external"`. 2. **Spend Currency**: The currency you spent in the trade, can be a token address (e.g., `eip155:1/erc20:0xdAC17F958D2ee523a2206206994597C13D831ec7`) or symbol (e.g., `BTC`). 3. **Spend Amount**: The amount of currency you spent. 4. **Receive Currency**: The currency you received in the trade, can be a token address or symbol. 5. **Receive Amount**: The amount of currency you received. 6. **Fee**: The amount charged for the trade. This is optional. 7. **Fee Currency**: The currency in which the fee was charged. This is optional. 8. **Description**: A description of the trade if any. This is optional. 9. **Timestamp**: The UTC Unix timestamp at which the trade took place. This is a milliseconds timestamp. A sample generic trades template can be found below: ### rotki Generic Events Import This is for importing generic events. Supported events are `"Deposit"`, `"Withdrawal"`, `"Income"`, `"Loss"`, `"Spend"` and `"Staking"`. The expected file format is **CSV** with the following headers and descriptions as a guide: 1. **Type**: The event type. It can be one of `"Deposit"`, `"Withdrawal"`, `"Income"`, `"Loss"`, `"Spend"` or `"Staking"`. 2. **Location**: This is the source of the data. It should be one of rotki's [supported locations](#supported-locations). If it is not supported, use `"external"`. 3. **Currency**: The currency used during the specified event. 4. **Amount**: The amount of the currency used by the event. 5. **Fee**: The amount charged for the event. This is optional. 6. **Fee Currency**: The currency in which the fee was charged. This is optional. 7. **Description**: A description of the event that was carried out, if any. This is optional. 8. **Timestamp**: The UTC Unix timestamp at which the event took place. This is a milliseconds timestamp. A sample generic events template can be found below: ### Supported Locations A list of supported locations in rotki are `"external"`, `"kraken"`, `"poloniex"`, `"bittrex"`, `"binance"`, `"bitmex"`, `"coinbase"`, `"banks"`, `"blockchain"`, `"gemini"`, `"equities"`, `"realestate"`, `"commodities"`, `"cryptocom"`, `"uniswap"`, `"bitstamp"`, `"binanceus"`, `"bitfinex"`, `"bitcoinde"`, `"iconomi"`, `"kucoin"`, `"balancer"`, `"loopring"`, `"ftx"`, `"nexo"`, `"blockfi"`, `"independentreserve"`, `"gitcoin"`, `"sushiswap"`, `"shapeshift"`, `"uphold"`, `"bitpanda"`, `"bisq"`, `"ftxus"` and `"okx"`. > **Note**: In the columns where an asset is expected, you will need to use the identifier that such asset has in rotki; otherwise, the row won't be read. > **Note**: If at any point, you're confused about the CSV format, feel free to send us a message on [Discord](https://discord.rotki.com). --- --- url: /requirement-and-installation.md description: 'Install rotki from pre-built binaries, run it in Docker, or build from source.' --- # Installation rotki runs locally on your machine — no accounts or cloud services are required to get started. Pick the path that matches your use case: ## System requirements | Requirement | Minimum | | ----------- | --------------------------------------------------------- | | **Linux** | Any modern 64-bit distribution with glibc 2.28+ | | **macOS** | Big Sur (11) or later, Intel or Apple Silicon | | **Windows** | Windows 10 (64-bit) or later | | **RAM** | 4 GB (8 GB recommended for large portfolios) | | **Disk** | 2 GB free for the app, plus space for your local database | ## What's next? Once rotki is installed, head to the [Quick Start Guide](/usage-guides/quick-start) for a step-by-step walkthrough from creating an account to generating your first PnL report. --- --- url: /usage-guides/settings/interface.md description: >- Customizing the rotki interface including language, theme, animations, balance refresh, and explorer links. --- # Interface Settings ## Interface-only Settings ![Customizing the app's interface only settings](/images/sc_interface_only_settings.png) #### Language Set the language used in the app. This feature is experimental and may not work as expected for some languages. Help us speed up the translation process by contributing [here](/contribution-guides/contribute-as-developer#add-a-new-language-or-translation). #### Animation Effect Reduce animation effects to improve performance. This affects animation quality but optimizes resource usage. #### Persist Table Sorting Save your table sorting preferences so they persist when you navigate away and return to the page. #### Data Scrambling Enable data scrambling to randomize amounts, dates, and other data for privacy in screenshots. This setting does not persist across sessions. #### Persist Privacy and Scramble Mode Settings When enabled, privacy mode and scramble settings are preserved across sessions. When disabled, these settings reset to defaults upon login. #### Automatic Balance Refresh Enable or disable automatic balance refresh and set the refresh interval. Disabled by default due to potential slow queries and rate limits. #### Periodic Status Query Set the frequency of backend data updates. Default is 5 seconds. #### Blockchain Explorer Customization Customize which explorer is used for transaction and address links. #### Progress Query Indicator on Dashboard Configure the history query progress indicator shown on the dashboard. You can set the minimum out-of-sync period (in hours) before the indicator appears, the dismissal threshold (in hours) controlling how long the indicator stays hidden after being dismissed, and reset the dismissal status to show all indicators again. ### Graph Settings #### Dashboard Graph Default Timeframe Set the default timeframe for the dashboard graph, which will be pre-selected upon login. #### Graph Basis Configure whether the graph y-axis starts at 0 or the minimum amount for the period. ### Alias Name for Addresses Enable or disable alias names for blockchain addresses. Aliases are obtained from `ENS`, `addressbook`, or `blockchain account label`. Change the order of resolution as needed. ### Newly Detected Tokens Configure how newly detected tokens are stored and pruned. You can set the maximum number of tokens to keep (oldest tokens exceeding this limit are pruned) and the retention period in days (tokens older than this are automatically removed). ### Theme Customization \[Premium] Premium users can customize colors for light or dark mode. ## Disabling the Tray Icon Disable the application tray icon by clicking the `View` menu entry in the application menu bar. Select `Display Tray Icon` to enable/disable the tray icon. --- --- url: /contribution-guides/manual-testing.md description: >- Manual testing checklist for rotki release binaries covering startup, trades, imports, and exchanges. --- # Manual Testing To ensure the final executable works as a complete package (including the UI), a bit of manual testing with the final binaries is required. This should eventually be reduced as the E2E test suite becomes more complete. Everything below that can be E2E tested should be. If time allows, test the following on the binaries for all OSes. If not, test on at least one. ## Startup ### New User * Create a new user and verify that it works, both with and without a premium key. With a premium key, ensure you can verify that pulling data from the server works. * Provide mismatched passwords and check that they are handled properly. * Provide incorrect premium keys and check that they are handled properly. ### Sign in Existing User * Sign in an existing user with an incorrect password and check that it is handled properly. * Sign in a non-existing user and check that it is handled properly. * Sign in an existing user and verify that it works. ## External Trades * Add an external trade and verify that it appears in the table. * Edit an external trade from the table and verify that the changes are saved. * Delete an external trade from the table and verify that it is removed. * Expand the details on a trade and check that they are shown properly. ## Data Importing * Import data from cointracking.info and verify that it works properly. ## Exchanges * Add an invalid exchange API key and check that it is handled properly. * Add a valid exchange API key and verify that it works. Ensure that dashboard balances are also updated. * Remove an exchange and verify that it works and that the dashboard balances are updated. ## External Services * Add an API key for all external services and verify that it works. * Remove an API key for all external services and verify that it works. ## Application and Accounting Settings * Change all application settings one by one and verify that the changes are reflected. * Enter invalid values (if possible) for application settings and check that they are handled properly. * Change the profit currency and verify that it works. * Change all accounting settings one by one and verify that the changes are reflected. * Enter invalid values (if possible) for accounting settings and check that they are handled properly. ## Accounts and Balances ### Fiat * Add a fiat balance and verify that it works. * Remove a fiat balance and verify that it works. * Check that adding non-numeric or negative values is handled properly. ### EVM Accounts * Add an EVM account to a single chain (e.g., Ethereum) and verify that it works. * Add an EVM account to all supported chains and verify that it is added to each chain. * Add an invalid EVM account and check that it is handled properly. * Remove an EVM account and verify that it works. * After adding tokens to an account that has them, expand the account and check that all tokens owned by it are shown. * Use the chain filter in the aggregated view to filter accounts by specific chains. * Toggle between aggregated assets view and per-chain assets view. ### EVM Tokens * Trigger token detection for all EVM accounts and verify tokens are discovered. * Trigger token detection for a single chain and verify it works. * Trigger token detection for a single account and verify it works. * Track an EVM token and verify that it is added: * In the dashboard. * In the owned tokens. * In total blockchain balances. * In the expanded asset details of EVM accounts that own it. * Remove an EVM token and verify that it is removed from all the above locations. ### Bitcoin Accounts * Add a Bitcoin account manually and verify that it works. * Add an invalid Bitcoin account and check that it is handled properly. * Remove a Bitcoin account and verify that it works. * Add an xpub and verify that addresses are automatically discovered. * Test different xpub types (P2PKH, P2SH-P2WPKH, WPKH, P2TR) and verify correct address generation. * Verify that ypub/zpub formats are automatically detected. ### Substrate Accounts * Add a Polkadot account and verify that it works. * Add a Kusama account and verify that it works. * Add an invalid Substrate account and check that it is handled properly. * Remove a Substrate account and verify that it works. ### Solana Accounts * Add a Solana account and verify that it works. * Add an invalid Solana account and check that it is handled properly. * Remove a Solana account and verify that it works. ## Tax Report * Check that invalid input in the date range is handled properly. * Create a large tax report covering many exchanges over a long period and verify that it is correct and no unexpected problems occur. * Create a CSV export of the report and verify that it works. ## Premium Analytics * Verify that premium analytics features work for a premium account. * Modify the range of the net value graph and check that it works properly. * Change the asset and modify the range of the graph of the amount and value of an asset and check that it works properly. * Verify that the net value distribution by location works properly. * Verify that the net value distribution by asset works properly and that you can modify the number of assets shown in the graph. ## Updating the Documentation rotki is continuously changing, and sometimes documentation becomes outdated. One way to contribute to rotki is by helping to keep the documentation up to date. To do so, you have to edit the corresponding section in the `.rst` files inside the `docs` folder of the git repo. To review your changes, you can compile the documentation using the command: ```sh make html ``` inside the `docs` folder. ### Guide Screenshots When updating the user guide documentation, you might need to update the application screenshots. ![Capturing screenshots](/images/contrib_screen.png) To be consistent, use the Chrome Developer Tools in the Electron application to capture the screenshots. First, toggle the device toolbar (1). If this is the first time you are taking a screenshot, click on the **Dimensions** dropdown menu and select **Edit** (2). ![Adding a custom screen resolution](/images/contrib_dimens.png) You will be given the option to **Add custom device**. Use the following settings: * **Resolution**: 1600x900 * **DPR**: 1 In the user agent, ensure that **Desktop** is selected. Then, save the entry. After making sure that this entry is selected, press the overflow menu (3) and select **Capture Screenshot** to capture a new screenshot. --- --- url: /usage-guides/history/onchain.md description: >- Sending on-chain transactions from rotki via WalletConnect or browser wallet on supported EVM chains. --- > \[!NOTE] > This is an experimental feature, and you may find some imperfections. However, we are going to continuously improve it. # Onchain Transactions rotki allows you to perform onchain transactions by connecting your wallet (either through a browser wallet or WalletConnect). At the moment rotki only supports sending native tokens and ERC-20 tokens on all supported EVM chains. ![Onchain send tokens](/images/onchain_send.png) ::: info You can only send tokens from an address that is registered as an EVM account in rotki. Otherwise, rotki won't be able to retrieve the list of tokens. ::: There are 2 ways to connect the wallet: ## Connect using Wallet Connect You can connect the wallet via Wallet Connect. For example, if you want to connect to the wallet on your phone, or by using Safe Wallet. 1. Select the tab `Wallet Connect` 2. Click `Connect Wallet` button and proceed from there ![Onchain wallet connect](/images/onchain_wallet_connect.png) ## Connect using Browser Wallet If you don't want to connect via Wallet Connect, you can also connect locally to your browser wallet. 1. Select the tab `Local` 2. Click `Connect Wallet` button 3. If you access rotki via the app, it will open a tab in your browser. It attempts to scan the wallet you have in your browser. You need to keep this browser tab open while doing transactions. ![Open browser wallet bridge](/images/onchain_browser_wallet_1.png) 4. Go back to your main app. You will see this popup after rotki scans which browser wallet you have. You can choose any and finish the connection. ![Select browser wallet](/images/onchain_browser_wallet_2.png) 5. If it's successful, it will look like this, and show your connected address on top. ![Browser wallet connection success](/images/onchain_browser_wallet_3.png) You're now connected and can perform transactions. ## Troubleshooting 1. **I keep getting a "could not coalesce" error:** If you get an error looking like this in the console: ``` Error: could not coalesce error (error={ "code": "INVALID_ARGUMENT", "message": "" }, payload={ "id": 6, "jsonrpc": "2.0", "method": "eth_sendTransaction", "params": [ { "from": "0xfoo", "gas": "0x5208", "nonce": "0x1f4", "to": "0x6ea158145907a1fac74016087611913a96d96624", "value": "0x38d7ea4c68000" } ] }, code=UNKNOWN_ERROR, version=6.14.0) ``` You can clear the cache (Help > Clear Cache), and then restart the app. 2. **Cannot switch chain from the app.** At the moment, if you connect using the browser wallet bridge, you can switch chains only through the wallet directly and not from the rotki app. --- --- url: /premium/payment-methods.md description: >- Managing saved credit/debit cards and setting default payment methods for rotki premium renewals. --- # Payment Methods Manage your saved credit/debit cards and payment preferences for rotki premium subscriptions. ## Accessing Payment Methods Visit the [payment methods page](https://rotki.com/home/payment-methods) at rotki.com to manage your saved payment methods. ## Overview The payment methods page allows you to: * View all saved credit/debit cards * Add new cards without making a purchase * Set a default card for subscription renewals (premium subscribers only) * Remove cards you no longer use * Update payment information for future renewals ::: info Automatic Card Saving When you purchase a subscription with a credit/debit card, it's automatically saved to your account and will appear on this page. This ensures renewals can process smoothly. ::: ## Adding a Payment Method ### Add Card Without Purchase You can save a card for future use without making an immediate purchase: 1. Go to the [payment methods page](https://rotki.com/home/payment-methods) 2. Click **Add Payment Method** or **Add Card** 3. Enter your card details: * Card number * Expiration date * CVV/CVC code 4. Click **Save** The card is now available for subscription purchases and renewals. ### Cards Added During Purchase When you buy a subscription with a credit/debit card: 1. Enter card details at checkout 2. Complete the payment 3. The card is **automatically saved** to your account 4. It will appear on the payment methods page 5. It's set as the default for future renewals ## Viewing Saved Cards From the [payment methods page](https://rotki.com/home/payment-methods), you can see: * **Card type** (Visa, Mastercard, Amex, etc.) * **Last 4 digits** of the card number * **Expiration date** * **Default status** (which card will be used for renewals) ::: info Security For security, only the last 4 digits of your card number are displayed. Full card numbers are never stored or shown. ::: ## Setting a Default Card Active premium subscribers can choose which saved card to use for renewals. ### How to Set Default Card 1. Go to the [payment methods page](https://rotki.com/home/payment-methods) 2. Find the card you want to use for renewals 3. Click **Set as Default** or select the default option 4. The selected card will be used for all future renewals ::: tip Premium Subscribers Only You must have an active premium subscription to set a default card. This feature ensures your subscription renews without interruption. ::: ### What Happens at Renewal When your subscription renews: * The default card is charged automatically * You receive a confirmation email * An invoice is generated and available on your [subscription page](https://rotki.com/home/subscription) * If payment fails, you're notified and can update your payment method ## Removing a Payment Method To delete a saved card: 1. Go to the [payment methods page](https://rotki.com/home/payment-methods) 2. Find the card you want to remove 3. Click **Delete** or the delete icon 4. Confirm the deletion ::: warning Removing the Default Card If you remove the card set as default for renewals: * Ensure you have another card saved * Set a new default card to avoid renewal failures * Or be prepared to manually renew your subscription ::: ## Updating Card Information You cannot directly edit a saved card. To update card details: 1. Add the new card as a payment method 2. Set it as the default (if needed) 3. Remove the old card This ensures secure handling of payment information. ## Payment Methods and Renewals ### Card Renewals Subscriptions paid with credit/debit cards renew automatically using your default card. **Before each renewal:** * Verify your default card is current and valid * Ensure sufficient funds are available * Check the expiration date hasn't passed ### PayPal Renewals If you paid with PayPal: * Renewals are processed through PayPal directly * You manage the payment source in your PayPal account settings * The payment methods page doesn't apply to PayPal subscriptions ### Crypto Subscriptions Crypto subscriptions are **not auto-renewable**: * Cards are not used or saved * You must manually repurchase when the subscription expires * See [Payment Process](/premium/payment#cryptocurrency-non-renewable) for details ## Troubleshooting ### My card won't save If you have trouble saving a card: 1. Verify all card details are entered correctly 2. Check the card is valid and not expired 3. Ensure your billing address matches your card's registered address 4. Try a different browser or clear cache 5. Contact if issues persist ### Renewal failed with my saved card If an automatic renewal fails: 1. Check the card hasn't expired 2. Verify sufficient funds are available 3. Contact your bank to ensure the charge wasn't blocked 4. Update your payment method if needed 5. Manually renew from the [pricing page](https://rotki.com/pricing) if necessary ::: tip Renewal Notifications You'll receive email notifications if a renewal fails, giving you time to update your payment method before your subscription expires. ::: ### Can't set a default card If you can't set a default card: 1. Verify you have an **active** premium subscription 2. Ensure the card is already saved to your account 3. Try refreshing the page 4. Contact for assistance ### I don't see my cards If saved cards aren't showing: 1. Verify you're logged in to the correct account 2. Check if you completed a card payment (crypto payments don't save cards) 3. Clear browser cache and reload 4. Try adding a card manually ## Security and Privacy ### How Card Data is Stored * Card details are processed and stored by Braintree (a PayPal company) * rotki.com never directly stores full card numbers * Only the last 4 digits and expiration date are displayed * All payment processing follows PCI DSS compliance standards --- --- url: /premium/payment.md description: >- Step-by-step guide to purchasing a rotki premium subscription including plan selection and payment. --- # Payment Process This guide walks you through the process of purchasing a rotki premium subscription. ## Step 1: Select Your Plan 1. Visit the [pricing page](https://rotki.com/pricing) 2. Review the available tiers and their features 3. Choose between monthly or yearly billing 4. Click the purchase button for your selected tier ::: tip Have a Referral Code? If you have a referral code, you can enter it during checkout to get 10% off your first subscription. See [Using a Referral Code](/premium/referrals#using-a-referral-code) for details. ::: ## Step 2: Apply Discount/Referral Code (Optional) If you have a referral code or discount code: 1. Look for the **Referral Code** or **Discount Code** input field during checkout 2. Enter your code 3. The discount will be applied to your purchase 4. Verify the discounted amount before proceeding See [Referral Program](/premium/referrals) for more information about referral codes. ## Step 3: Choose Payment Method rotki premium supports three payment methods. Choose the one that works best for you: ### Credit/Debit Card (Auto-Renewable) Pay with your credit or debit card for automatic renewals. **Benefits:** * Automatic monthly or yearly renewals * No need to manually repurchase * Manage cards from [payment methods page](/premium/payment-methods) **How it works:** 1. Enter your card details at checkout 2. Complete the payment 3. Your card is automatically saved for future renewals 4. Subscription renews automatically until canceled ::: tip Saved Cards Cards used for subscription payments are automatically saved to your account. You can view and manage them from the [payment methods page](https://rotki.com/home/payment-methods). If you have multiple saved cards, you can set your preferred card for renewals (premium subscribers only). ::: **Payment Processor:** Braintree (a PayPal company) ### PayPal (Auto-Renewable) Pay through your PayPal account for automatic renewals. **Benefits:** * Automatic monthly or yearly renewals * Use your existing PayPal balance or linked payment methods * Secure PayPal authentication **How it works:** 1. Select PayPal as your payment method 2. Log in to your PayPal account 3. Review and approve the payment 4. Subscription renews automatically through PayPal until canceled ::: info PayPal Subscriptions Your PayPal subscription can also be managed from your PayPal account settings. However, we recommend managing it from your [rotki subscription page](https://rotki.com/home/subscription) for the best experience. ::: ### Cryptocurrency (Non-Renewable) Pay with cryptocurrency for a one-time subscription period. **Benefits:** * Privacy-focused payment option * No recurring charges * Support for various cryptocurrencies **How it works:** 1. Select crypto as your payment method 2. Choose your preferred cryptocurrency 3. Transfer the **exact amount** shown to the provided address 4. Wait for blockchain confirmation ::: warning Important: Non-Renewable Crypto subscriptions do **NOT** automatically renew. When your subscription expires, you'll need to manually purchase a new subscription. **Exact Amount Required:** You must transfer the exact amount displayed. The system detects payments automatically, but only if the amount matches precisely. ::: **Supported cryptocurrencies:** Check the payment page for the current list of supported coins. ## Step 4: Payment Confirmation After completing payment: 1. You'll receive a confirmation email 2. An invoice will be generated and available on your [subscription page](https://rotki.com/home/subscription) 3. Your premium subscription is now active ## Step 5: Activate your subscription in the App After successful payment, you need to manually generate your API credentials and add them to the rotki application. 1. Create your API key via the [subscription page](https://rotki.com/home/subscription) 2. Navigate to **API Keys** → **rotki Premium** in the app and enter your **API Key** and **API Secret** See [API Keys & Secrets](/premium/api-keys) for detailed instructions. ## Invoices and Receipts All payment invoices are automatically generated and stored in your account. **To access invoices:** 1. Go to your [subscription page](https://rotki.com/home/subscription) 2. View the payment history section 3. Download invoices as needed ## Payment Issues ### Payment Failed If your payment fails: 1. Verify your payment details are correct 2. Check that you have sufficient funds 3. Contact your bank or payment provider 4. Try an alternative payment method ### Crypto Payment Not Detected If your crypto payment isn't detected: 1. Verify you sent the **exact amount** shown 2. Check the transaction on the blockchain explorer 3. Wait for sufficient confirmations 4. Contact with your transaction hash if issues persist ### Renewal Failed If an automatic renewal fails: 1. Check your [payment methods](https://rotki.com/home/payment-methods) 2. Verify your card hasn't expired 3. Ensure sufficient funds are available 4. Update your payment method if needed ::: tip You'll receive email notifications before renewals and if renewal attempts fail, giving you time to update payment information. ::: --- --- url: /premium/plans-and-pricing.md description: >- Comparing rotki premium subscription tiers, billing cycles, and choosing the right plan. --- # Plans & Pricing rotki premium offers multiple subscription tiers with varying limits and capacities to suit different user needs. ## Viewing Available Plans Visit the [pricing page](https://rotki.com/pricing) to view: * All available subscription tiers * Feature comparison across tiers * Device limits per tier * Pricing for monthly and yearly billing ## Subscription Types Choose between **monthly** or **yearly** billing. Yearly subscriptions provide better value. ::: info Billing Details * The full amount is charged immediately * Automatically renews each billing period (monthly or yearly) until you cancel * New billing cycle starts at UTC midnight after the subscription expires * An invoice is generated for each payment, accessible from your [account page](https://rotki.com/home/subscription) * Can be canceled from the account page at any time ::: ## Choosing a Tier Each tier provides different limits and capacities. Consider the following when choosing: * **Number of devices**: How many devices will you use rotki on simultaneously? * **Transaction volume**: How many transactions do you process? * **Advanced features**: Do you need specific premium-only integrations? Review the [pricing table](https://rotki.com/pricing) for detailed feature comparisons. ## Custom Plans If none of the standard tiers meet your requirements, custom plans are available. ::: tip Request a Custom Plan Contact to discuss: * Your specific needs * Custom device limits * Custom feature requirements * Custom pricing ::: ## Understanding Billing ### Billing Cycle * Billing cycles start at **UTC midnight** after your subscription expires * You'll receive an email notification before renewal * Invoices are automatically generated and available in your account ### Automatic Renewal Subscriptions automatically renew based on the payment method: * **Card payments**: Auto-renewed using your saved card * **PayPal payments**: Auto-renewed via PayPal * **Crypto payments**: **NOT auto-renewed** - you must manually purchase again See [Payment Process](/premium/payment) for details on each payment method. ### Cancellation You can cancel your subscription at any time from your [subscription page](https://rotki.com/home/subscription). ::: warning Canceling prevents future renewals but does not provide refunds for the current billing period. You'll retain premium access until the end of your paid period. ::: See [Subscription Management](/premium/subscription) for cancellation instructions. ## Upgrading Your Subscription You can upgrade to a higher tier directly from your [subscription page](https://rotki.com/home/subscription). ### How to Upgrade 1. Go to your [subscription page](https://rotki.com/home/subscription) 2. Select a higher tier from the available options 3. The payment will be prorated based on your remaining days in the current plan 4. Complete the payment to activate the upgraded tier immediately ::: info Prorated Billing When you upgrade, you only pay the difference between your current tier and the new tier, adjusted for the remaining time in your current billing period. ::: ::: warning Downgrades Not Supported You cannot downgrade to a lower tier. If you need a lower tier, you must cancel your current subscription and wait for it to expire before subscribing to the lower tier. ::: ## Next Steps * [Choose your plan](https://rotki.com/pricing) and proceed to checkout * Learn about [payment methods](/premium/payment) * Set up [API keys](/premium/api-keys) after purchasing --- --- url: /premium.md description: >- Overview of rotki premium subscription tiers, features, and how to get started with premium. --- # Premium Overview rotki premium is a paid subscription with several tiers unlocking additional features depending on your needs while supporting the ongoing development of rotki as an open-source project. ## What is rotki Premium? rotki's base version will always remain open-source and free to use. Premium subscriptions help fund development and provide access to enhanced features that improve your experience. When you subscribe to rotki premium, you get: * Extended portfolio tracking capabilities * Advanced analytics and reporting features * Cloud backup and sync across multiple devices * Premium-only integrations (Monerium, Gnosis Pay, etc.) * Priority support * And more To see the complete list of premium features and current pricing, visit [rotki.com/products](https://rotki.com/products/). ## Getting Started with Premium Here's a quick overview of how to set up and use rotki premium: ### 1. Choose a Plan Browse available subscription tiers at [rotki.com/pricing](https://rotki.com/pricing). Each tier offers different limits and capacities to match your needs. If none of the standard tiers fit your requirements, you can request a custom plan by contacting . See [Plans & Pricing](/premium/plans-and-pricing) for details. ### 2. Complete Payment Choose from three payment methods: * **Crypto** - Manual transfer (renewal is done manually) * **Credit/Debit Card** - Auto-renewable * **PayPal** - Auto-renewable See [Payment Process](/premium/payment) for step-by-step instructions. ### 3. Generate Your API Keys After successful payment, generate your **API Key** and **API Secret** by clicking the **Create** button on your [subscription page](https://rotki.com/home/subscription). For detailed instructions, see [Creating API Keys](/premium/api-keys#creating-api-keys). ### 4. Add Keys to the App Navigate to **API Keys** → **rotki Premium** in the rotki application and enter the **API Key** and **API Secret** generated in the last step to activate the premium features included in your subscription. For detailed instructions, see [Using API Keys in the App](/premium/api-keys#using-api-keys-in-the-app). ## Managing Your Premium Subscription Once you have an active subscription, you can manage various aspects through your rotki.com account: ### [Subscription Management](/premium/subscription) * View subscription details and status * Access payment history and invoices * Create and manage API keys * Create referral codes * Cancel your subscription ### [Payment Methods](/premium/payment-methods) * Add and save credit/debit cards * Set default card for renewals * Remove saved payment methods ### [Device Management](/premium/devices) * View all devices using your API key * Edit device names * Remove unused devices * Monitor device limits ### [Referral Program](/premium/referrals) * Generate referral codes * Share codes for 10% off (for new subscribers) * Track referral benefits (coming soon) --- --- url: /contribution-guides/python-testing.md description: >- Running the Python test suite, linting with ruff/mypy/pylint, and mocking network calls in tests. --- # Python Code Testing To run the Python test suite, ensure you have installed all dependencies including the dev group, and then execute: ```sh uv run python pytestgeventwrapper.py -xs rotkehlchen/tests ``` We require this wrapper as a drop-in replacement for pytest due to quirks with gevent and monkeypatching. For more specific usage and invocation of the tests, please refer to the [pytest documentation](https://docs.pytest.org/en/stable/usage.html). We run the test suite in GitHub CI but only a subset of the tests since not all are needed and sometimes they suffer from rate limiting. We have special settings to choose which tests are executed: * `[skip py tests]` will not run the Python backend tests regardless of whether the backend code has been touched. * `[run nft py tests]` will run the base set of tests and the tests related to NFTs. * `[run all py tests]` will run the base set of tests, the tests related to NFTs, and some others that perform a large number of requests and are slower. ## Linting Before each commit, you should run the linting checks. They run `ruff`, `mypy`, and `pylint` in order. Invoke these checks by running `make lint` from the root directory of the project. ## Mocking Networking in the Tests One of the biggest issues we have at rotki is that backend testing is really slow, primarily due to network calls. As rotki is a portfolio tracking and analytics tool, almost all of our tests involve network calls. We are in the process of trying to rectify this. For repetitive network calls that can be recorded, we started using vcr.py as stated in [this issue](https://github.com/rotki/rotki/issues/5373). The problem with vcr.py is that it is limited by the size of the cache in the CI. Therefore, it might still make sense to manually mock certain network calls. There is a useful way to run tests by disallowing network calls, which helps detect if a test makes any non-mocked network calls. We use the [pytest-socket](https://pypi.org/project/pytest-socket/) module to achieve this. You can add `--disable-socket` to any pytest call, and it will fail immediately for any network calls. You will probably also need to add `--allow-hosts=127.0.0.1` if the tests make local network calls to the rotki API. This way, you can discover all network calls and mock them. Mocking should be done in one of the following ways: 1. Using common fixtures for data mocking as shown [here](https://github.com/rotki/rotki/pull/5269). Read the PR description to get an idea. 2. Using test-specific mocking. 3. For repeatable calls that would always return the same response from the network, use the vcr.py approach. ## Using VCR From version 1.27.0, we have introduced VCR to mock network queries in most tests to improve the speed of the test suite. VCR works by generating a `yaml` file that records information about all the requests made. Then, for every request that occurs in the test, VCR tries to match it to one of the recorded ones. We already have some pre-recorded cassettes (the name used by VCR for those yaml files), which are available on [GitHub](https://github.com/rotki/test-caching). During a fresh run, this repository will be cloned, and the cassettes will be replayed. This occurs in the path set by the `vcr_cassette_dir` fixture, which also sets the directory where the cassettes are located. By default, this is the `test-caching` directory under [rotki's data directory](/usage-guides/advanced/data-directory#rotki-data-directory). Locally, cassettes are only read and never written to prevent unexpected behavior during testing. To record a new test, we provide a make rule called `create-cassette`. ### In the Tests First, we need to mark the test as a VCR test with the pytest directive: ```python @pytest.mark.vcr ``` For tests that make requests with parameters depending on time, block number, or anything else that can vary between runs, it is also necessary to mock them during the test execution. For mocking time, we use freezegun: ```python @pytest.mark.freeze_time('2023-01-24 22:45:45 GMT') ``` You can change the time here to match the one at which you are writing the test. ### Recording a Test To execute the test and record it: ```sh RECORD_CASSETTES=true python pytestgeventwrapper.py -m vcr TEST_PATH ``` Here, we set `RECORD_CASSETTES` to change the configuration of VCR to allow writing to files, and with `-m vcr`, we only run a test if it has the VCR mark. This rule can be executed with: ```sh make create-cassette TEST_PATH ``` ### Handling Errors When executing tests mocked with VCR after making changes to the code, you might encounter the following error: ```sh vcr.errors.CannotOverwriteExistingCassetteException: Can't overwrite existing cassette ``` This error indicates that a new request not recorded in the cassette occurred and needs to be added. To resolve this, use the `RECORD_CASSETTES` approach to update the yaml file if it was intentional. If no new requests are supposed to be made, investigate and figure out what is happening. ### Syncing with the Cassettes Repository When working on a new branch, you might need to either create a new cassette or update an existing one. Suppose you are working on branch `new_cool_feature` based on `bugfixes`. In that case, you will need to go to the cassettes repository [rotki/test-caching](https://github.com/rotki/test-caching) and create a branch with the same name, `new_cool_feature`, based on that repository's `bugfixes` branch. If you don't have permission to create a new branch in `rotki/test-caching`, fork the repository, create the branch in your fork with the same name as your branch from the main repository, and create a PR from this branch to rotki/test-caching's target branch (bugfixes/develop). Locally, you can work with your rotki branch, and rotki will ensure to pull the proper cassette branch during testing. The logic for this is [here](https://github.com/rotki/rotki/blob/20534a679a0f1bc7951fa21496aaa5eab976ae1b/rotkehlchen/tests/conftest.py#L225). This works fine in the CI and should always pull the proper branch. However, it may happen that it falls back to a branch like `develop` instead of `bugfixes` when running locally. To solve this, utilize the `DEFAULT_VCR_BRANCH` environment variable to run a test locally like this: ```sh DEFAULT_VCR_BRANCH=bugfixes python pytestgeventwrapper.py -xs --pdb rotkehlchen/tests/unit/test_evm_tx_decoding.py::test_genesis_remove_address ``` When you record a new cassette or update an existing one, all changes will be saved in the local test-caching repository. Make sure to commit this and push it to the upstream branch so that your PR in rotki's CI also works. If you encounter issues when re-recording a cassette, you can simply delete and re-record it from scratch. After your `new_cool_feature` PR is merged into rotki (e.g., bugfixes in our example), the CI will merge the test-caching branch with the same name or the PR that was created previously. ## Alternative Linting and Static Analysis Tools There are some alternative linting tools that we don't run in the CI since they generate many false positives. It's good to run them occasionally, so they are listed here. * **vulture**: Source and documentation [here](https://github.com/jendrikseipp/vulture). Install it via `pip install vulture`. Running it from the root directory will provide a list of possibly unused code that you can remove. Be prepared for many false positives. * **bandit**: Source and documentation [here](https://github.com/PyCQA/bandit). Install it via `pip install bandit`. Running it will highlight potential issues in the code, but expect many false positives. --- --- url: /usage-guides/quick-start.md description: >- Step-by-step walkthrough to get started with rotki, from installation to generating your first PnL report. --- # Quick Start Guide This guide walks you through the essential steps to get rotki up and running. By the end, you'll have your accounts connected, balances visible, and know how to generate a tax report. > \[!TIP] > **Focused on tax reporting?** This quick start covers the essentials. For a dedicated walkthrough tailored to tax reporting — including connecting data sources, reviewing transactions, and handling edge cases — see the [Tax Accounting Guide](/usage-guides/tax-accounting/guide). ## 1. Install rotki Download and install rotki for your operating system from the [official website](https://rotki.com/download) or follow the detailed [Installation Guide](/requirement-and-installation/). ## 2. Create Your Account When you first launch rotki, you'll be prompted to create a local account. This account exists only on your device — rotki doesn't store your data on any server. ![rotki login screen](/images/rotki_login_screen.png) 1. Click **Create Account** 2. Choose a profile name 3. Set a strong password — this encrypts your local database ![Creating a new account](/images/rotki_create_account.png) > \[!WARNING] > Do not forget your password. It encrypts all your local data and cannot be recovered. If you have a premium subscription, you can link it during account creation to enable cloud backup and sync. See [Accounts & Sync](/usage-guides/) for full details. ## 3. Optimize Your Setup Before adding accounts, set up a few things to make account detection and balance queries much faster: * **Etherscan API Key** — Free and significantly speeds up EVM queries (and is required for some chains like Binance Smart Chain). Go to **API Keys → External Services** and add your key. See [External Services](/usage-guides/integrations/external-services#etherscan). * **Custom RPC Nodes** — Add your own RPC endpoints (e.g., from Alchemy or Infura) for faster blockchain queries. Configure in **Settings → Blockchain & EVM → RPC Nodes**. See [RPC Node Settings](/usage-guides/settings/blockchain#rpc-node-setting). * **Indexer Configuration** — Adjust the order of indexers (Etherscan, Blockscout, Routescan) per chain for optimal performance. See [Indexers](/usage-guides/settings/blockchain#indexers). > \[!TIP] > At minimum, we strongly recommend adding a free Etherscan API key **before** adding your blockchain accounts. Without it, EVM queries and token detection will be significantly slower. ## 4. Add Your Accounts ### Blockchain Accounts Navigate to **Accounts** in the sidebar and add your blockchain addresses: 1. Select the chain category (EVM, Bitcoin, Substrate, or Solana) 2. Click **Add Account** 3. Enter your address and click **Save** For EVM addresses, you can select **All Supported Chains** to automatically detect activity across all EVM networks. ![Add a blockchain account](/images/add_blockchain_account.png) See [Accounts](/usage-guides/portfolio/accounts) for details on xpub support, multi-address imports, and more. ### Exchange Connections To track exchange balances and trade history: 1. Go to **API Keys → Exchanges** in the sidebar 2. Click **Add an exchange** 3. Enter your read-only API key and secret ![Add API keys for an exchange](/images/rotki_add_exchange_1.png) See [Exchange API Keys](/usage-guides/integrations/exchange-keys) for the full list of supported exchanges and per-exchange setup instructions. ## 5. View Your Portfolio Once your accounts are connected, head to the [Dashboard](/usage-guides/portfolio/dashboard) to see your portfolio overview: ![rotki Dashboard](/images/rotki_dashboard.webp) The dashboard shows: * **Total Balance** — Your combined net worth across all sources * **Net Value Graph** — Historical portfolio value over time * **Balance Breakdown** — Split by exchange, blockchain, and manual balances * **Assets Table** — All holdings sorted by value rotki will automatically query balances and detect tokens for your tracked accounts. This initial sync may take a few minutes depending on how many accounts and chains you have. ## 6. Review Your History Navigate to **History → Events** to see all your transactions, trades, and DeFi interactions. rotki automatically decodes on-chain transactions and categorizes them by event type. ![History Events page](/images/events_filter.png) You can: * Filter events by type, time period, or asset * Edit events that were decoded incorrectly * Add manual events for off-chain activity See [Historical Events](/usage-guides/history/events) for the full guide. ## 7. Generate a Tax Report When you're ready to calculate your taxes: 1. Go to **Profit and Loss Report** in the sidebar 2. Select the reporting period (start and end dates) 3. Review your [Accounting Settings](/usage-guides/settings/accounting) — these control how trades are calculated (FIFO, LIFO, HIFO, or ACB) and whether to apply a tax-free holding period 4. Click **Generate** ![PnL Report](/images/sc_pnl_report.png) The report calculates profit and loss for every taxable event in the period, broken down by event type (trades, fees, staking rewards, airdrops, etc.). You can export the results as CSV for your tax advisor, and re-run the report with different settings if needed. > \[!IMPORTANT] > Tax rules vary by jurisdiction. Before filing, consult a tax professional and adjust your accounting settings to match your local requirements. See [Profit/Loss Report](/usage-guides/history/pnl) for detailed instructions and the [Tax Accounting Guide](/usage-guides/tax-accounting/guide) for a comprehensive walkthrough. ## Next Steps * **[Settings](/usage-guides/settings/general)** — Customize your profit currency, display preferences, and more * **[Data Management](/usage-guides/data-management/assets)** — Manage assets, add missing prices, and organize with tags * **[Premium Features](/premium/)** — Unlock extended timeframes, advanced analytics, cloud sync, and more --- --- url: /premium/referrals.md description: >- Creating and using rotki premium referral codes for discounts on first subscriptions. --- # Referral Program Share rotki premium with others and both you and your referrals benefit. ## Overview The rotki referral program allows premium subscribers to share rotki with friends, colleagues, and the community. When someone uses your referral code: * **For the referee** (person using the code): 10% off their first subscription * **For the referrer** (you): Benefits coming soon - stay tuned! ::: tip Premium Subscribers Only You must have an active premium subscription to create and share referral codes. ::: ## Creating a Referral Code 1. Go to your [subscription page](https://rotki.com/home/subscription) 2. Navigate to the **Referral** section 3. Click **Create** 4. Your unique code will be created 5. Copy and share your code ## Using a Referral Code If someone shared a referral code with you: 1. Go to the [pricing page](https://rotki.com/pricing) 2. Select your desired subscription tier 3. Proceed to checkout 4. Look for the **Referral Code** input field 5. Enter the referral code 6. Your 10% discount will be applied to your first subscription ::: info First Subscription Only The 10% discount applies only to the first subscription purchase. Renewals and subsequent subscriptions are charged at full price. ::: ## Benefits for Referrers ### Current Status Benefits for referrers (people sharing codes) are **coming soon**. We're working on implementing rewards for users who successfully refer others to rotki premium. Stay tuned for announcements! ### Discount Limitations For referees: * 10% discount applies to first subscription only * One referral code per subscription * Cannot be combined with other promotions (unless specified) ## Troubleshooting ### I can't create a referral code If you can't create a referral code: 1. Verify you have an **active** premium subscription 2. Check your subscription hasn't expired or been canceled 3. Refresh the page and try again 4. Contact for assistance ### My referral code isn't working If someone reports your code doesn't work: 1. Verify the code was entered correctly (check for typos) 2. Ensure the code field is visible during checkout 3. Confirm your premium subscription is still active 4. Contact support with the specific error message ### The discount isn't applying If the 10% discount doesn't show: 1. Confirm the referral code was entered in the correct field 2. Check for error messages about the code 3. Try entering the code again (copy/paste to avoid typos) 4. Ensure it's a first-time subscription (renewals aren't discounted) 5. Contact with details ### I lost my referral code If you forgot your referral code: 1. Go to your [subscription page](https://rotki.com/home/subscription) 2. Check the Referral section - your code should be displayed 3. If not shown, contact for assistance ### Where do I enter a referral code? When using someone's referral code: 1. Select a plan on the [pricing page](https://rotki.com/pricing) 2. Click to purchase 3. Look for the **Referral Code** or **Promo Code** field during checkout 4. Enter the code before completing payment 5. Verify the discount is applied before finalizing --- --- url: /contribution-guides.md description: >- How to contribute to rotki including bug reporting, debug mode, feature requests, and development setup. --- # rotki Contribution Guide rotki is an open-source project, so help is really appreciated. ## Bug Reporting You can report issues directly from within rotki via **Help & Support** (in the app sidebar) > **Report Issue**. This opens a dialog where you enter a title and description, then choose to submit via GitHub (pre-fills a bug report template), a Google Form, or email. If you prefer, you can also report issues through GitHub or Discord as described below. Before reporting an issue, make sure to check the issue tracker for similar ones. If this is a new issue, then use the [proper template](https://github.com/rotki/rotki/issues/new?template=bug_report.md) providing a detailed description about: * **Problem**: What happened and what you were expecting to happen instead. * **Logs**: Run rotki in debug mode, replicate the issue, and attach the logs (see the section [Run rotki in debug mode](#run-rotki-in-debug-mode)). * **Environment**: The operating system and the rotki version. ## Run rotki in debug mode For running rotki in debug mode, you can do it either via a config file or the app UI. The choice will depend on how you run rotki. * **Config file**: See the section [Set the backend's arguments](/usage-guides/advanced/backend-config#set-the-backend-s-arguments). This is possible in the **electron app** and the **docker version**. For docker, you can even use environment variables as explained [here](/requirement-and-installation/docker#configuring-the-backend). * **App UI**: Before logging in, click the cogwheel in the bottom right corner and select "Debug" (image below). Press the save button and proceed to log in as usual. This is only possible in the **electron app**. ![Run rotki in debug mode via app UI](/images/rotki_debug_mode_set.png) You can open the app logs location by going to the "Help" menu at the top and then choosing "Logs Directory". The default log locations are: * **Linux**: `~/.config/rotki/logs` * **OSX**: `~/Library/Application Support/rotki/logs` * **Windows**: `%APPDATA%\rotki\logs` Logs created by running in debug mode will contain private data such as addresses. To try and reduce the amount of private data in the logs, you can optionally run a `regex` find and replace script on your log file. [Here](https://gist.github.com/iSpeakNerd/7261feaf97d25a55d173cedeb4568544) is an example script. It is included in the docs for inspiration and will catch some instances of private data but not all. **Do not** make any assumptions about the logs and only share them with rotki developers. If you write a script that is over-censoring and important data are redacted, we may ask you to give us the uncensored logs. --- --- url: /usage-guides/advanced/data-directory.md description: >- Default rotki data directory locations on Linux, macOS, and Windows, plus backup recommendations. --- # rotki data directory rotki saves user data by default in a different directory per OS. For each OS, data is stored in the respective standards-compliant equivalent directory. * **Linux**: `~/.local/share/rotki/data/` * **OSX**: `~/Library/Application Support/rotki/data` - please note this folder is hidden by default * **Windows**: `%LOCALAPPDATA%/rotki/data` Before v1.6.0, rotki was saving data in `$USER/.rotkehlchen`. From v1.6.0, that directory got migrated to the OS equivalent standard directory, and it should be safe for users to delete the old directory as long as the new directory contains the migrated DB. A very good idea for the rotki data directory would be to make frequent backups of it as it contains all of the data of all of your rotki accounts and cache data for historical price queries. ## Data directory for unreleased development code If you are running rotki from unreleased code from git branches, please note that [the data directory is in a slightly different location](/contribution-guides/contribute-as-developer#working-with-the-develop-branch). --- --- url: /contribution-guides/rotki-database.md description: >- Architecture of rotki's SQLite databases, schema upgrades, data migrations, and cache management. --- # rotki Database rotki uses two different SQLite databases: one with information about assets, prices, and other non-sensitive information (`global.db`), and one with user information (`rotkehlchen.db`). The latter is encrypted using an extension called [SQLCipher](https://github.com/sqlcipher/sqlcipher) that provides transparent 256-bit AES full database encryption. ## Database Location Databases are stored in directories under the [rotki data directory](/usage-guides/advanced/data-directory#rotki-data-directory). * The global database is stored at `global/global.db`. * The accounts you create in rotki have their own database stored at `users//rotkehlchen.db`. If you need to manually access the database, you can find the guide [here](/usage-guides/advanced/database-access#accessing-the-database-manually). ## DB Upgrades Database upgrades are needed when changes in the schema occur. rotki checks a setting in the database with the version and executes a check against the version to verify if the upgrade needs to happen. When the database schema is changed, it is important to note that **the operation is not reversible**. Therefore, to open the upgraded database with an older version, you would need a backup. For more information, check [upgrade\_manager.py](https://github.com/rotki/rotki/blob/da7062220abddc7bde9b99fc3d297412bb6552b4/rotkehlchen/db/upgrade_manager.py). When adding a new upgrade, remember to bump `ROTKEHLCHEN_DB_VERSION` in [settings.py](https://github.com/rotki/rotki/blob/da7062220abddc7bde9b99fc3d297412bb6552b4/rotkehlchen/db/settings.py). Generally, we only make one upgrade per release, so if you need to make changes to the schema, simply add them to the latest unreleased migration. rotki generates a backup before any schema upgrade. These backups are stored in the same directory as the database with the name `_rotkehlchen_db_v.backup` or `_global_db_v.backup`. rotki uses the same mechanism of updating the schema for both the global and user databases. ## DB Migrations When developers need to make changes in the data but the schema does not change, a data migration is made instead. This operation can be a simple task such as deleting old backup files, inserting some rows, or running a background task to update some table. In this case, the database can be opened using the previous version of rotki. For more information, check [data\_migrations](https://github.com/rotki/rotki/tree/develop/rotkehlchen/data_migrations). --- --- url: /usage-guides/advanced/backend-config.md description: >- Customizing rotki backend arguments via rotki_config.json for log levels, data directories, and more. --- # Set the backend's arguments rotki runs a Python daemon on the backend. Most times you won't need to customize its arguments, but if you need to do so, especially for debugging purposes, this is how you can. Create or edit (if it exists) a file with the name `rotki_config.json` in the same directory as the rotki executable. Add to the JSON object any arguments that are also arguments of rotki. Then when rotki starts, these will be passed as arguments to the backend. An example `rotki_config.json` follows: ```json { "loglevel": "debug", "logfromothermodules": false, "log-dir": "/path/to/dir", "data-dir": "/path/to/dir", "sleep-secs": 20, "max_size_in_mb_all_logs": 500, "max_logfiles_num": 2 } ``` --- --- url: /usage-guides/staking.md description: >- How to track ETH2 validator staking, Liquity staking, Kraken staking, and Lido CSM node operation in rotki. --- # Staking rotki currently supports staking tracking for: 1. Ethereum (ETH2) 2. Liquity 3. Kraken 4. Lido CSM ## ETH2 Staking You can track ETH2 staking in 2 ways: 1. Add the ETH account that deposited funds for the validator - this automatically detects and tracks associated validators. 2. Add a validator manually: * Go to `Accounts → EVM Account > Validators` * Click `Add account` * Enter the validator's public key and/or index * Optional: Set ownership percentage if sharing the validator ![Track an ETH2 validator](/images/eth2_add_validator.png) After adding a new validator you will see a list showing the status and balance of each validator. Validator status may be `PENDING`, `ACTIVE`, `EXITING`, `EXITED`, or `CONSOLIDATED`. Validators with a status of `CONSOLIDATED` have been merged with another validator. Consolidation was introduced in Ethereum's Pectra upgrade with EIP-7251 raising the maximum effective balance from 32 ETH to 2048 ETH. To take advantage of the higher limit a validator must first be converted into an accumulating validator, changing its withdrawal credentials from `0x00` or `0x01` to `0x02`. Once converted, additional ETH can be deposited into the validator, and other validators can be consolidated into it combining their balances. rotki detects consolidation via the execution layer consolidation request transaction (see an example transaction [here](https://etherscan.io/tx/0x812eeeb8a786650afa1826d8e9d46aa2073e28f1ed261f0c3da4ea18b7d7cd82)). ![ETH2 validator balances](/images/eth2_validators.png) View your ETH staking details under menu `Staking > ETH`. ETH2 stakers can track their earnings both at current ETH prices and based on the value of daily staking rewards. Validator profit is calculated from several different sources: * Outstanding CL (Consensus Layer) rewards - The amount by which the validator's current balance exceeds the maximum effective balance (32 or 2048 ETH depending on if its an accumulating validator). * CL skimming withdrawals - Profit withdrawn from the validator on the consensus layer. Accumulating validators also support user requested partial withdrawals that are not profit, so rotki detects partial versus skimming withdrawals by checking if there is a corresponding execution layer withdrawal request transaction. * Block and MEV rewards - rotki must be tracking the receiving address to count these in the validator's profit. * Exits - When a validator is exited the profit is calculated as the exited amount minus the deposited amount. ![ETH2 validator stats](/images/rotki_eth2_staking.png) These earnings are included in profit/loss reports and can be exported to CSV for further analysis. ## Liquity Staking If you stake LQTY in the protocol you can see stability pool deposits, staked amount, and the stake events. ![See your Liquity staking gains](/images/sc_staking_liquity.png) On the left side, we display information for your current deposited amount of `LUSD` in the stability pool along with the `ETH` and `LQTY` rewards that you haven't claimed yet. On the right side, we display the staked `LQTY` and the `ETH` and `LUSD` that are available to claim. The Liquity statistics are calculated using the queried events and you might need to wait for some time until all the events are queried to get the final values. The values in terms of USD can be displayed using prices at the moment of the different events (`historical`) or using prices at the present (`current`). * Total Gains Stability Pool: This is the value of Ether and `LQTY` claimed from the stability pool. * Total Deposited Stability Pool: This is the value of `LUSD` deposited in the stability pool. * Total Withdrawn Stability Pool: This is the value of `LUSD` withdrawn from the stability pool. * Stability Pool Gains: A breakdown of the gains already claimed from the pool. * Estimated PnL: This value represents your returns from the stability pool after losing LUSD in exchange for `ETH` and `LQTY`. For more information on how the stability pool works check [the Liquity docs](https://docs.liquity.org/faq/stability-pool-and-liquidations#how-do-i-benefit-as-a-stability-provider-from-liquidations). This amount is calculated in rotki as follows: ``` A = Total Deposited Stability Pool - Total Withdrawn Stability Pool LG = Claimed Liquity gains in current price. R = Not claimed rewards in current price. B = Total Gains Stability Pool + LG + R C = (A - Current deposited amount) in current price PnL = B - C ``` For `LQTY` staking we display the claimed rewards. ![Liquity Statistics](/images/liquity_stats.png) ## Kraken Staking If you stake on Kraken you can see your gains, and events in the various staked assets. ![See your Kraken staking gains](/images/sc_staking_kraken.png) ## Lido CSM If you are a node operator in the [Lido Community Staking Module (CSM)](https://operatorportal.lido.fi/modules/community-staking-module), you can track your operators in rotki. Navigate to `Staking > Lido CSM` to view and manage your tracked node operators. To add a node operator, click the add button and provide: * **Ethereum address** — the reward address associated with the node operator. * **Node Operator ID** — the numeric ID assigned to your operator in the CSM. Once added, the table displays the following metrics for each tracked operator: * **Operator Type** — the operator category (e.g. Community, Permissioned). * **Bond Current / Required / Claimable** — current bond posted, required bond, and the amount available to claim, all denominated in stETH. * **Total Deposited Keys** — the number of validator keys deposited. * **Pending Rewards** — unclaimed stETH rewards. Click the refresh button to fetch updated metrics from the protocol. You can remove a tracked operator at any time using the delete action in the table. --- --- url: /usage-guides/statistics.md description: >- Viewing net value graphs, asset amount/value charts, and balance snapshots with rotki premium. --- # Statistics If you have a premium subscription you can get statistics on all your assets and trades. Click on the `Statistic > Graph` page on the left sidebar to go to your statistics page. ## Net value over time Since rotki is tracking all your assets over time the first thing you can see is a value/time graph of your entire net value. > \[!NOTE] > This graph shows your data from the day you first used the app, as rotki takes daily snapshots. In the future, we plan to show older data using historical events, where possible (see [this issue](https://github.com/rotki/rotki/issues/1379)). ![Net value over time graph](/images/sc_stats_netvalue.png) Following that you can see a graph of quantity of an asset superimposed on its USD value over time. ## Asset amount and value over time ![Asset amount and value over time](/images/sc_stats_asset_amount_value.png) We have introduced an option in the asset graphs to select the `Missing snapshot multiplier`. It sets after how many hours between two snapshots the graph will display zero balances. This allows to improve graphs for periods where the balance of an asset was zero. ![Multiplying option in assets graphs](/images/statistics_multipliying_option.png) All the assets graphs as well as the dashboard graph have the possibility of selecting a range for zooming. This can be done by left clicking and dragging on the graph itself or using the selector under the graph. The graph can be zoomed out by double clicking on it. ![Zooming in the graphs](/images/zooming_in_graph.png) ### Use historical events and prices ![Asset amount and value from historical events processing](/images/asset_amount_and_value_from_historical.png) By default, the asset amount and value use snapshot data, which is typically taken daily (depends on the setting). If you want to view more detailed data, you can use `Historical events and prices`. If you haven't fetched the prices before, some points might be hidden. You can click `Fetch prices`, and rotki will attempt to fetch the prices and also populate the graph with daily prices, allowing you to observe price movements over time. Additionally, you can `Remember your selection` for each asset. So when you reopen the graph for the asset, it will remember the source. ### Compare "historical events and prices" and "snapshot" data. You can show both sources at the same time to compare the data directly: 1. You need to select "Historical events and prices" as the source. 2. By default, the snapshot data is hidden in this graph. You need to enable it by clicking the legend on the button. (Clicking on the legend will toggle the corresponding line on the chart.) ![Asset amount and value legend](/images/asset_amount_and_value_legend.png) ### Mismatch between amount from historical events and current balance ![Asset amount and value warning](/images/asset_amount_and_value_warning.png) Sometimes you might see this warning, if there is mismatch between amount at the last event with amount in current balance. Here are the possible reasons: 1. The history events or the balances haven't fully loaded. If this is the case, you need to wait until all sources are queried. 2. You have a manual balance that increases the amount, but you haven't specified the custom event to acquire the asset. Conversely, you have custom events (e.g., from a CSV import), but you haven't specified the manual balance. 3. The asset is accruing value in staking or defi LPing but there is no event yet for this accrual. 4. Some of your events are not properly decoded by rotki, or there may be missing events or there may be mistakes in the custom events you created. ## Value distribution by location Furthermore, you can see a pie chart of the distribution of your net value across different locations. So you can determine how exposed you are to having a big part of your net value in exchanges, in banks e.t.c. ![Distribution of networth by location](/images/sc_stats_distribution_location.png) ## Value distribution by asset Moreover, you can see a pie chart of the distribution of your net value across all the assets you own. This is an important analytics tool as it can help you determine your exposure on each asset and if some re-balancing of your portfolio is in order. ![Distribution of networth by asset](/images/sc_stats_distribution_asset.png) > \[!NOTE] > The pie charts showing value distribution by location and asset use data from your latest snapshot, not your current balance. To see the most recent data, you'll need to [create a new snapshot](/usage-guides/portfolio/balances#balances-snapshots). ## Event Analysis It's available under the `Statistic > Event Analysis` menu. You can view the summary of your activities by checking your history events data, including ETH spent, exchanges/protocols used, and Gnosis Pay usage. ![Event Analysis](/images/event_analysis.png) --- --- url: /premium/subscription.md description: >- Managing your rotki premium subscription, viewing payment history, canceling, and renewing plans. --- # Subscription Management Manage your rotki premium subscription, view payment history, and access your API keys from your account page. ## Accessing Your Subscription Visit your [subscription page](https://rotki.com/home/subscription) at rotki.com to manage your premium account. ## Viewing Subscription Details Your subscription page displays: * **Current plan tier** (Basic, Advanced, etc.) * **Billing cycle** (Monthly or Yearly) * **Subscription status** (Active, Expired, Canceled) * **Next renewal date** (for active subscriptions) * **Device usage** (current devices vs. limit) ## Managing API Keys API Keys and Secrets are required to connect the rotki app to your premium subscription. You need to manually generate them from the API Keys section on your subscription page. See [API Keys & Secrets](/premium/api-keys) for detailed instructions on creating, viewing, regenerating, and securing your API credentials. ## Payment History View all past payments and invoices from your subscription page. ### Accessing Invoices 1. Go to your [subscription page](https://rotki.com/home/subscription) 2. Scroll to the Payment History section 3. View details for each payment: * Date * Amount * Payment method * Invoice status 4. Download invoices as needed ::: info Invoice Generation An invoice is automatically generated for each payment and available immediately after successful payment. ::: ## Creating Referral Codes Premium subscribers can create referral codes to share with others. People using your code get 10% off their first subscription. See [Referral Program](/premium/referrals) for detailed instructions on creating and sharing referral codes. ## Canceling Your Subscription You can cancel your subscription at any time from your subscription page. ### How to Cancel 1. Go to your [subscription page](https://rotki.com/home/subscription) 2. Click the **Cancel Subscription** button 3. Confirm the cancellation ### After Cancellation ::: warning Important * Cancellation takes effect at the end of your current billing period * You retain premium access until the paid period ends * No refunds are provided for the remaining time in your current period * Your API keys will stop working after the subscription expires ::: ### Reactivating After Cancellation If you've canceled your subscription but it hasn't expired yet, you can resume it: 1. Go to your [subscription page](https://rotki.com/home/subscription) 2. Click the **Resume Subscription** button 3. Your subscription will continue and auto-renew as before ::: tip Resume Before Expiration You can only resume a subscription before it expires. Once expired, you'll need to purchase a new subscription from the [pricing page](https://rotki.com/pricing). ::: ## Changing Your Plan ### Upgrading to a Higher Tier You can upgrade directly from your subscription page: 1. Go to your [subscription page](https://rotki.com/home/subscription) 2. Select a higher tier 3. Payment will be prorated based on remaining time 4. The upgrade takes effect immediately See [Upgrading Your Subscription](/premium/plans-and-pricing#upgrading-your-subscription) for detailed information. ### Downgrading or Changing Billing Cycle To downgrade to a lower tier or change your billing cycle (monthly ↔ yearly): 1. Cancel your current subscription 2. Wait for the current billing period to end 3. Subscribe to your desired tier from the [pricing page](https://rotki.com/pricing) ::: warning No Downgrades Downgrades are not supported. You must cancel and wait for your subscription to expire before subscribing to a lower tier. ::: ## Renewal Information ### Automatic Renewal Subscriptions automatically renew based on your payment method: * **Card**: Charged automatically using your default card * **PayPal**: Charged automatically via PayPal * **Crypto**: **NOT auto-renewed** - you must manually repurchase ### Billing Cycle New billing cycles start at **UTC midnight** after your subscription expires. ### Renewal Notifications You'll receive email notifications: * Before your subscription renews * After successful renewal * If renewal payment fails ### Managing Renewal Payment Method For card payments, you can change which card is used for renewals: 1. Go to your [payment methods page](https://rotki.com/home/payment-methods) 2. Set your preferred card as the default 3. Future renewals will use the selected card See [Payment Methods](/premium/payment-methods) for details. ## Troubleshooting ### My subscription shows as expired but I paid 1. Check your payment was successful in your bank/PayPal account 2. Verify payment was sent to the correct address (for crypto) 3. Check your email for payment confirmation 4. Contact with payment details ### My renewal failed 1. Check your [payment methods](https://rotki.com/home/payment-methods) 2. Verify your card hasn't expired 3. Ensure sufficient funds are available 4. Update your payment method if necessary 5. Manually renew from the [pricing page](https://rotki.com/pricing) if needed ### I can't access my subscription page 1. Ensure you're logged in to rotki.com 2. Verify you're using the correct account 3. Clear browser cache and try again 4. Contact for assistance --- --- url: /usage-guides/data-management/tags.md description: >- Creating and editing tags with custom labels, descriptions, and colors for organizing accounts and balances. --- # Tag Management You can find the menu on the left sidebar. ![Tag Manager](/images/tag_manager.png) ## Adding/Editing Labels and tags You can add or edit tags from this view. You can also create a new tag when you are adding your blockchain account or manual balance. The label is unique, so you can't create multiple tags with the same label. ![Create a tag](/images/add_tag.png) --- --- url: /usage-guides/portfolio/accounts.md description: >- Adding and managing blockchain accounts (EVM, Bitcoin, Substrate, Solana) and exchange connections. --- # Tracking Accounts To manage Blockchain Accounts, you need to visit the `Accounts` section from the left sidebar. ![Blockchain accounts page](/images/accounts.png) ## Blockchain Accounts rotki allows to track balances of blockchain accounts. For now, the following chains are supported in rotki (and the list will be growing as we add more chains in the future): | Chain Type | Blockchain | Chain ID for importing purposes | | -------------------- | ------------------- | ------------------------------- | | **EVM Chains** | Ethereum | eth | | | Optimism | optimism | | | Polygon PoS | polygon\_pos | | | Arbitrum One | arbitrum\_one | | | Base | base | | | Gnosis | gnosis | | | Scroll | scroll | | | Binance Smart Chain | binance\_sc | | | Avalanche | avax | | | zkSync Lite | zksync\_lite | | | | | | **Bitcoin Chains** | Bitcoin | btc | | | Bitcoin Cash | bch | | | | | | **Substrate Chains** | Polkadot | dot | | | Kusama | ksm | | | | | | **Solana Chains** | Solana | solana | ### Steps to Add an Account: 1. Go to the chain category sub-page 2. Click `Add Account` (top right) 3. Select your blockchain 4. Enter the address in `Account` textbox 5. Click `Save` ### Adding Multiple Accounts: * Check `Add multiple addresses` box * Enter addresses as comma-separated list ### Adding Account to all EVM Chains * Choose `All Supported Chains` in the chain selector. ![Add a blockchain account](/images/add_blockchain_account.png) You can edit or delete an account using the buttons at the end of the row. For editing, you can modify the label or the tags. > \[!WARNING] Account detection on Binance SC > > We verify whether an address should be tracked by querying its on-chain activity through the indexers you have configured. > Since Binance Smart Chain is not accessible under the free tier for any supported indexer, a paid Etherscan API key is required to detect activity there. If that key is not provided, BSC address detection will not work. ### Bitcoin Chains There are two ways to add your Bitcoin or Bitcoin Cash addresses to rotki: 1. Manual entry of individual addresses 2. Using an xpub (extended public key) for automatic address discovery #### What is an xpub? An xpub is a special key that lets rotki find all your wallet addresses without giving access to your funds. When you provide an xpub, rotki will: * Generate your addresses locally * Query the blockchain activity for each address * Stop when it finds unused addresses * Store this information securely in your local database #### Types of XPUB | Type | Common Name | Address Starts With | Description | | ----------- | ------------- | ------------------- | ----------------------------------- | | P2PKH | Legacy | "1" | The original Bitcoin address format | | P2SH-P2WPKH | Segwit | "3" | More efficient than legacy | | WPKH | Native Segwit | "bc1" | Most efficient for transactions | | P2TR | Taproot | "bc1p" | Newest type with enhanced privacy | #### How to Use Your xpub 1. Check what type of addresses your wallet generates 2. Select the matching type in rotki's dropdown menu > \[!INFO] Good to know > > * If your xpub starts with "ypub" or "zpub", rotki will automatically detect the correct type > * For Ledger hardware wallet users, you can get your xpub by following [this guide](https://support.ledger.com/article/6275459128989-zd) > * Bitcoin Cash only works with Legacy (P2PKH) and Segwit (P2SH\_P2WPKH) addresses ![Add a bitcoin account using XPUB](/images/add_xpub_key.png) ### Aggregated view filtering In the EVM Chains section, the chain selection allows you to filter accounts based on specific blockchain networks. This functionality works as a filter, meaning you can click on any chain, like Ethereum, Gnosis, or Polygon, and view only the accounts that are associated with those chains. You can even filter by multiple chains simultaneously. ![Filter or delete a blockchain account](/images/filter_chains.png) Additionally, there is an option to toggle between viewing the aggregated assets across all chains or displaying the assets per individual chain. This provides flexibility, allowing you to either get a total balance view from all chains at once or focus on specific chain assets. ![Filter or delete a blockchain account](/images/aggregated_view_per_chain.png) ### ENS names resolution rotki automatically resolves ENS name and ENS avatar for every EVM address that has ENS name set in ethereum mainnet. If there is a primary ENS name specified for an address, this name will be shown instead of a raw blockchain address across the app. You can find the blockchain address by hovering the mouse over the ENS name. If an ENS avatar is set, it will be shown instead of the address blockie. ### Token detection For EVM accounts, it is possible to trigger the process of detecting tokens before refreshing the balances. There are several ways to do that: ![Refresh all accounts tokens](/images/refresh_all_accounts_tokens.png) 1. To re-detect tokens for all EVM accounts in all chains, go to the dashboard and toggle the arrow here. You can change the default behavior of the refresh button to `Re-detect tokens and refresh balances` and then click the refresh button. ![Refresh particular accounts tokens](/images/refresh_particular_account_tokens.png) 2. To re-detect tokens for all addresses of one EVM chain, click `Re-detect tokens` in the EVM accounts section. 3. To re-detect tokens for only one account, click the refresh button in the corresponding row. ### Import and Export Blockchain Accounts (CSV) You can export your blockchain accounts to CSV and then import them again into another rotki account (if you need to do it for your tax accountant, etc.). Also, if you have many accounts that you want to add to rotki, you can create your CSV and import it into rotki. You can do it in from any submenu from the menu `Accounts` by clicking the three-dot menu. ![Import and Export Blockchain Accounts](/images/import_and_export_blockchain_accounts.png) 1. The `address` field is **required**. For an xpub, input the xpub address. For a validator, input the publicKey. 2. The `address extras` field is **optional**. You can specify `ownershipPercentage=xx` for validators and `derivationPath=xx` for xpubs. 3. The `chain` field is **required**. You can find supported chain IDs in the [supported blockchain](#blockchain-accounts) section. Use `evm` to add to all EVM chains. 4. The `label` field is **optional**. 5. The `tags` field is **optional**. Multiple tags should be separated by semicolons (`;`). ### Blockchain aggregated balances You can see the list of aggregated assets from Blockchain Accounts from menu `Balances > Blockchain Balances`. You can also see the breakdown of the assets, which locations they belong to, whether they are in the wallet, or being put into some protocol. ![Aggregated list of assets from blockchain accounts](/images/sc_blockchain_balances.png) ### Loopring balances From the balances section you can quickly get an overview of the accounts having balances in Loopring and what assets these accounts hold. ![Loopring balances detailed per address](/images/loopring_balances_detailed.png) --- --- url: /usage-guides/advanced/troubleshooting.md description: >- Fixing common rotki issues such as login errors, frontend settings corruption, and data problems. --- # Troubleshooting ## Invalid input error during login These errors happen due to an invalid value in the frontend settings While the should not typically happen, it can occur due to a bug in the frontend. The error appears as a red alert in the page with a message like this:. ![Redecode events for a transaction](/images/ts_profit_loss.png) In this case, the problem is with the `'profitLossReportPeriod'`, so to fix it, you need to modify the `profit_loss_report_period/` field in the frontend settings. To do so: 1. Open the browser developer tools and go to the Console. * Ctrl + Shift + I on Windows/Linux * Cmd + Option + I (⌘ + ⌥ + I) on macOS 2. Then proceed to modify the part of the code that sets the value of the field. Paste it in the console and run it. For example to fix the `profitLossReportPeriod` field you would need to run the following code: ```js /* eslint-disable unicorn/prefer-top-level-await */ fetch('http://127.0.0.1:4242/api/1/settings') .then(response => response.json()) // Parse JSON response .then((data) => { const result = data.result; const frontend_settings = result.frontend_settings; const parsed = JSON.parse(frontend_settings); parsed.profit_loss_report_period = { quarter: 'ALL', year: '2025', }; const stringified = JSON.stringify(parsed); fetch('http://127.0.0.1:4242/api/1/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ settings: { frontend_settings: stringified, }, }), mode: 'cors', // Enable CORS }); }) .catch((error) => { console.error('Error:', error); }); ``` ::: tip You can also use the same approach to modify other values in the settings by changing the fields in `parsed` and sending them back with the `PUT` request. ::: --- --- url: /usage-guides/tax-accounting/guide.md description: >- Step-by-step walkthrough for calculating crypto taxes with rotki, from data setup to PnL report generation. --- # Using rotki for Tax Accounting This guide walks you through using rotki to calculate your cryptocurrency taxes. If you just installed rotki and want to generate a tax report, this is the page for you. > \[!NOTE] > rotki does not provide tax or legal advice. Always consult a qualified tax advisor for your specific situation. rotki helps you organize your data and generate reports that you can share with your advisor. ## Overview The two most important sections of rotki for tax accounting are: 1. **[History Events](/usage-guides/history/events)** — where you review, correct, and customize all of your transactions 2. **[Profit/Loss Report](/usage-guides/history/pnl)** — where you generate the actual PnL (profit and loss) report for a given time period Everything else in rotki (adding accounts, importing data, configuring settings) feeds into these two sections. ## Step-by-step tax workflow ### 1. Connect your data sources Before you can generate a tax report, rotki needs to know about your transactions. * **Exchanges**: Add API keys for your centralized exchanges under [API Keys](/usage-guides/integrations/exchange-keys). rotki will automatically pull your trade history, deposits, and withdrawals. * **Blockchain accounts**: Add your EVM, Bitcoin, or Solana addresses under [Accounts & Balances](/usage-guides/portfolio/accounts). rotki will pull and decode on-chain transactions automatically. * **CSV imports**: For exchanges that don't support API integration (or that no longer exist, like FTX), you can [import CSV files](/usage-guides/history/import-data) with your trade history. ### 2. Configure your accounting settings Go to **Settings → Accounting Settings** ([detailed reference](/usage-guides/settings/accounting)) and configure: * **Cost basis method**: FIFO, LIFO, HIFO, or ACB — check which method your tax jurisdiction requires. See [accounting rule options explained](/usage-guides/tax-accounting/accounting-rules) for details. * **Crypto to crypto trades**: Whether swapping one crypto for another is a taxable event (it is in most jurisdictions). * **Tax-free period**: If your country allows tax-free treatment after a holding period (e.g., Germany's 1-year rule), set it here. * **Profit currency**: The fiat currency your taxes are denominated in (e.g., EUR, USD, GBP). Change this via the currency icon in the top-right menu. ### 3. Review your history events Go to **History Events** in the left sidebar. This is where all your transactions live. rotki automatically decodes most on-chain transactions, but you should review them for accuracy: * **Check for missing events**: If you moved assets through unsupported protocols or peer-to-peer, you may need to [add events manually](/usage-guides/history/events#add-edit-events). * **Fix incorrectly categorized events**: rotki may not always correctly identify what a transaction represents. See the [event types and subtypes reference](/usage-guides/tax-accounting/event-types) to understand each category, and the [common customization guide](/usage-guides/history/events#common-customization) for how to re-categorize events. * **Check for missing accounting rules**: Events with a warning icon won't be processed correctly. Either edit the event or add a [missing accounting rule](/usage-guides/history/events#missing-accounting-rule). * **Match asset movements**: If you have exchange deposits/withdrawals that aren't linked to on-chain transactions, use the [asset movement matching](/usage-guides/history/events#unmatched-asset-movements) feature. ### 4. Add missing prices Some assets or time periods may not have price data available from rotki's oracles. Go to **Add Missing Prices** ([guide](/usage-guides/data-management/prices)) to manually specify prices for assets that rotki can't find automatically. ### 5. Generate your PnL report 1. Click **Profit and Loss Report** in the left sidebar 2. Select the time period (e.g., the tax year) 3. Click **Generate** The report shows: * A summary of total profit/loss and how much is taxable * A detailed table of every event that contributed to the calculation * The cost basis for each sell event (where the sold assets were originally acquired) ### 6. Export and review * Click **Export CSV** to download the report for use in Google Sheets or LibreOffice * Share the export with your tax advisor for review * See the [PnL report guide](/usage-guides/history/pnl#results-of-the-pnl-report) for column definitions ## Common issues and how to fix them | Problem | Likely cause | Solution | | --------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | | "No documented acquisition found" | rotki doesn't know when/where you originally bought an asset | [Add a manual trade](/usage-guides/history/events#add-edit-events) or acquisition event | | Event counted as taxable when it shouldn't be | Wrong event type/subtype | [Edit the event](/usage-guides/history/events#common-customization) to the correct type | | Missing price for an asset | Oracle doesn't have data for that asset/timestamp | [Add missing price manually](/usage-guides/data-management/prices) | | PnL numbers seem wrong | Accounting settings may not match your jurisdiction | Review [accounting settings](/usage-guides/settings/accounting) and [accounting rule options](/usage-guides/tax-accounting/accounting-rules) | | Report generation gets stuck | Often caused by exchange API rate limits | Check [troubleshooting](/usage-guides/history/pnl#pnl-report-generation-gets-stuck) | ## What rotki currently does NOT support Understanding what's not available saves you time: * **Custom cost basis overrides**: You cannot set an arbitrary cost basis for assets you already hold (e.g., market price on a specific date when moving tax jurisdictions). The workaround is to add a manual trade that represents the acquisition at the desired price. This is tracked in [rotki/rotki#9816](https://github.com/rotki/rotki/issues/9816). * **Custom counterparty definitions in accounting rules**: Accounting rules can be set per counterparty, but only for counterparties that rotki already recognizes (protocol identifiers like "uniswap", "aave", etc.). You cannot define your own custom smart contract as a counterparty for accounting rule purposes. This is tracked in [rotki/rotki#9803](https://github.com/rotki/rotki/issues/9803). ## Further reading * [Event types and subtypes reference](/usage-guides/tax-accounting/event-types) — what each event category means * [Accounting rule options explained](/usage-guides/tax-accounting/accounting-rules) — detailed explanation of every accounting setting * [Profit/Loss Report guide](/usage-guides/history/pnl) — full report documentation * [History Events guide](/usage-guides/history/events) — managing and customizing your transaction history * [Import CSV](/usage-guides/history/import-data) — importing data from unsupported exchanges --- --- url: /usage-guides/advanced/mobile.md description: >- Accessing rotki from a mobile device using DAppNode VPN or Docker with an authenticated proxy. --- # Using rotki from mobile If you are using DAppNode or the Docker image instead of the Electron application, it is possible to access rotki from a mobile device. ## DAppNode If you are running rotki on a DAppNode, then in order to access rotki on mobile the only thing needed is to set up a [VPN connection](https://docs.dappnode.io/user-guide/ui/access/vpn/) between DAppNode and your phone or tablet. You can use either Wireguard or OpenVPN by following the guide linked above. When you are done with the configuration, you can activate the VPN connection on your device. With the VPN activated, you will be able to access rotki on `http://rotki.dappnode`. ![rotki running on DAppNode accessed from a mobile device](/images/rotki_dappnode_mobile.png) This way you can get the full rotki functionality on mobile. ## Docker Accessing rotki on mobile when you run Docker on your own can be a bit complicated and depends on the kind of setup you have. You have to make sure that [rotki is never directly accessible from a public network](/requirement-and-installation/docker). One way to have rotki accessible on mobile over a public network is by making sure that an [authenticated proxy](#docker-rotki-public) intercepts all traffic directed to rotki. This way you can ensure that no one else can access your rotki instance. If you followed the authenticated proxy example from above, you should be able to access rotki's interface by going to `https://rotki.example.com` on your phone or tablet. Alternatively, if you already have a VPN setup to your private network or on the machine, you could use this VPN connection to securely connect to the rotki instance that runs on this network machine. ![rotki warning for docker](/images/rotki_docker_warning.png) For awareness reasons, if the app is run in Docker, you will see this warning every time it is opened. You can turn it off by running the rotki Docker image with this environment variable: ```sh ROTKI_ACCEPT_DOCKER_RISK=1 ``` --- --- url: /usage-guides/utilities.md description: >- Quick-access utilities in rotki including global search, in-app notes, and background task management. --- # Utilities ## Global Search You can use global search provided to speed up your actions by clicking the icon on the top bar, or using the shortcut `Control-/` (`Command-/` if you are using Mac). Some actions provided by this global search: * Navigate to any page in rotki * Some basic actions such as adding a new trade. * Go to a certain owned asset overview page. * Go to a certain location overview page. ![Global Search](/images/global_searchbox.gif) ## Taking Notes In-App You can now take notes in various sections of the application. Note taking is categorized into two types: 1. **General Notes**: These are notes available & visible across the application. ![General notes](/images/rotki_general_notes.png) 2. **Location-specific Notes**: These are notes restricted to the location in which they were created in the application. ![Location specific notes](/images/rotki_location_specific_notes.png) You can also pin notes; the pinned notes will appear at the top. ## Background Tasks A list of processing tasks is available on the notifications tray. ![running background tasks](/images/pending_tasks.png) It is possible to cancel a long running task, but use this feature sparingly. ![cancel background task](/images/pending_tasks_cancel.png) --- --- url: /requirement-and-installation/verify.md description: >- Verify the integrity and authenticity of rotki binaries using SHA512 checksums and GitHub Artifact Attestations. --- # Verify Your Download Verifying your download confirms that the binary you downloaded is the exact file that was built and published by the rotki team. This is optional, but recommended if you want to protect yourself from supply chain attacks or tampered mirrors. There are two independent ways to verify a rotki binary: 1. **SHA512 checksum** — quick integrity check against a published hash 2. **GitHub Artifact Attestations** — cryptographic proof that the binary was built from the official rotki source on GitHub You only need to do one of these to trust a binary; doing both gives you the strongest guarantee. ## SHA512 Checksums Starting with v1.6.2, every rotki binary on the [releases page](https://github.com/rotki/rotki/releases) ships with a matching `.sha512` file. Download both and run the platform-specific command below. ### Linux ```sh cd ~/Downloads sha512sum -c rotki-linux_x86_64-vx.x.x.AppImage.sha512 # rotki-linux_x86_64-vx.x.x.AppImage: OK ``` ### macOS ```sh cd ~/Downloads shasum -a 512 -c rotki-darwin-vx.x.x.dmg.sha512 # rotki-darwin-vx.x.x.dmg: OK ``` ### Windows Open Command Prompt in the download folder and compute the hash: ```sh cd Downloads certutil -hashfile rotki-win32-vx.x.x.exe SHA512 ``` The output will look like: ```sh SHA512 hash of rotki-win32-v1.6.2.exe: a3e0d79724460f642245774ba1af4c7116dfde56503d134c688f406afff5339f70a84a0bdb2556bc0785931b11e2447e3ffcd116cdec9e8a50382ec0165788b4 CertUtil: -hashfile command completed successfully. ``` Open the `.sha512` file with Notepad and confirm the hash matches the one above. ### If the checksum doesn't match If the hashes don't match, you should see an error similar to: ```sh rotki-linux_x86_64-vx.x.x.AppImage: FAILED sha512sum: WARNING: 1 computed checksum did NOT match ``` **Do not run the binary.** Re-download it from the official [releases page](https://github.com/rotki/rotki/releases) and try again. ## Publisher Signature You can also confirm the publisher by inspecting the binary's digital signature: * **Windows** — right-click the installer and open **Properties → Digital Signatures**. The signer should be `Rotki Solutions GmbH`. * **macOS** — right-click the app and choose **Get Info**. The copyright should read `Rotki Solutions GmbH`. ## GitHub Artifact Attestations rotki uses **GitHub Artifact Attestations** to cryptographically link each released binary back to the commit and workflow that produced it. This provides protection against supply chain attacks by confirming that the binary was genuinely built from the expected repository, commit, and build environment. You can verify attestations with the [GitHub CLI](https://cli.github.com/manual/gh_attestation_verify): ```sh gh attestation verify ~/Downloads/rotki134.dmg --repo rotki/rotki ``` Expected output: ``` Loaded digest sha256:12bb7aa1cf8d5b568f925e7c772b946a29efaf66ae030026a1f113da528c8e39 for file:///Users/you/Downloads/rotki134.dmg Loaded 1 attestation from GitHub API ✓ Verification succeeded! sha256:12bb7aa1cf8d5b568f925e7c772b946a29efaf66ae030026a1f113da528c8e39 was attested by: REPO PREDICATE_TYPE WORKFLOW rotki/rotki https://slsa.dev/provenance/v1 .github/workflows/rotki_release.yaml@refs/tags/v1.34.0 ``` > \[!WARNING] > GitHub artifact attestations will fail for Windows binaries (`rotki-win32_x64-*.exe`) published after August 2025. These binaries are re-signed locally using a hardware key (Yubikey) with an OV Certificate, which causes the binary hash to change after attestation. For Windows binaries after that date, verify that the binary is signed by **Rotki Solutions GmbH** instead. --- --- url: /contribution-guides/vue-typescript.md description: >- Running Vue/TypeScript unit tests with vitest and end-to-end tests with Playwright for the rotki frontend. --- # Vue/TypeScript ## Testing The Vue/TypeScript part of the application under the `frontend` directory has two types of tests. ### Unit Tests The unit tests, which test functions and components, use `vitest` and `vue-test-utils`. You can run them with: ```sh pnpm run --filter rotki test:unit ``` These are small tests ensuring that parts of the code work well in isolation. **Unit test file naming**: `.spec.ts` files should follow the naming of the tested file and be located in the same folder. ``` src/modules/balances/use-balances-store.ts src/modules/balances/use-balances-store.spec.ts src/composables/accounts/use-account-import-export.ts src/composables/accounts/use-account-import-export.spec.ts ``` ### End-to-End Tests The second type of tests is an end-to-end (`e2e`) test suite using [Playwright](https://playwright.dev/). The e2e tests require the Python environment with all dependencies installed because they depend on the actual Python backend. These tests ensure proper e2e functionality and application integration and try to replicate scenarios of real user interaction through the application. To run the e2e tests, use the following command inside the frontend directory: ```sh pnpm run --filter rotki test:e2e ``` The above command will run the e2e tests in headless mode. If you want to debug specific tests, you can also run: ```sh pnpm run --filter rotki test:e2e:ui ``` This command will open the Playwright UI mode where you can select specific tests to execute and see detailed traces. ## Linting If you are doing frontend development, it is highly recommended to enable the available hooks: ```sh pnpm run setup:hooks ``` Now you should have a pre-commit hook that runs whenever you commit a file and lints the staged files. > \[!NOTE] > If the hook was installed successfully, you should see lint-staged running every time you commit. Before committing and pushing your commits, ensure that you fix any lint issues. You can do this by running: ```sh pnpm run lint:fix ``` > **Note:** While lint warnings are not fatal and will not fail the CI pipeline, it would be better if a PR reduces the number of warnings and doesn't introduce new ones. Warnings are things that need to be fixed, and they will be converted to errors in the future. ## Code Organization & Maintainability * **Split complex logic**: Break down large templates and script logic into smaller, focused composables. * **Component decomposition**: Split large components into smaller, reusable sub-components. * **Logical separation**: Each composable should have a single, well-defined responsibility. * **Maintainability focus**: Prioritize code readability and maintainability over brevity. ## Vue ### Explicit TypeScript Typing Always use explicit types for `ref()`, `computed()`, and function return types. Use `get()` and `set()` from VueUse instead of `.value` when working with refs. If a ref type can be undefined and the default value is undefined, don't explicitly put it as type or default value — just use `ref()`. Always use `{ useScope: 'global' }` parameter for `useI18n()`. Use `startPromise()` instead of `void` for floating promises. **Correct:** ```typescript import { startPromise } from '@shared/utils'; import { get, set } from '@vueuse/shared'; const isVisible = ref(true); const count = ref(0); const items = ref([]); const user = ref(); // type is User | undefined, no need to specify undefined const { t } = useI18n({ useScope: 'global' }); const isEven = computed(() => get(count) % 2 === 0); const formattedName = computed(() => `${get(firstName)} ${get(lastName)}`); function getUserById(id: number): User | undefined { return get(users).find(user => user.id === id) || undefined; } function updateCount(newValue: number): void { set(count, newValue); } async function fetchData(): Promise { return await $fetch('/api/data'); } startPromise(someAsyncFunction()); ``` **Incorrect:** ```typescript // ❌ Missing explicit types const isVisible = ref(true); const count = ref(0); const items = ref([]); const user = ref(); // ❌ Missing useScope const { t } = useI18n(); // ❌ Using .value instead of get()/set() const isEven = computed(() => count.value % 2 === 0); const formattedName = computed(() => `${firstName.value} ${lastName.value}`); // ❌ Don't explicitly put undefined as type or default value const newId = ref(undefined); // ❌ Missing return types function getUserById(id: number) { return users.value.find(user => user.id === id) || undefined; } async function fetchData() { return await $fetch('/api/data'); } // ❌ Never use void for floating promises // eslint-disable-next-line no-void void someAsyncFunction(); ``` ### Setup Script Macros When using the `defineProps` or `defineEmits` macros in the setup script, the `defineX<{}>()` format should be used instead of `defineX({})`. Any instances of `defineX({})` should eventually be replaced with `defineX<{}>()`. For `defineEmits<{...}>()` before the migration to vue 3 the verbose style was used. When you encounter such entries, try to replace with the short style instead. e.g. **Before** ```typescript const emit = defineEmits<{ (e: 'update:msg', msg: string): void; }>(); ``` **After** ```typescript const emit = defineEmits<{ 'update:msg': [msg: string]; }>(); ``` #### Props — Destructured with Defaults (Vue 3.5+) Prefer destructuring props with defaults directly from `defineProps`: ```typescript const { title, count = 0, disabled = false } = defineProps<{ title: string; count?: number; disabled?: boolean; }>(); ``` For mutable defaults (arrays, objects), use factory functions: ```typescript const { items = () => [], filters = () => ({}) } = defineProps<{ items?: string[]; filters?: Record; }>(); ``` The legacy `withDefaults` pattern should be avoided in new code: ```typescript // ❌ Legacy pattern const props = withDefaults(defineProps<{ title: string; count?: number; disabled?: boolean; }>(), { count: 0, disabled: false, }); ``` #### defineModel (Vue 3.4+) Use `defineModel` for v-model bindings instead of manual prop + emit patterns: ```typescript const modelValue = defineModel({ required: true }); const selected = defineModel('selected'); const filters = defineModel('filters', { default: () => ({}) }); ``` **Incorrect** — do not use manual prop + emit for v-model: ```typescript // ❌ Do NOT do this const props = defineProps<{ modelValue: string }>(); const emit = defineEmits<{ 'update:modelValue': [value: string] }>(); ``` #### Template Refs (Vue 3.5+) Use `useTemplateRef` for template refs: ```typescript import { useTemplateRef } from 'vue'; const formRef = useTemplateRef>('formRef'); ``` ```vue-html ``` **Incorrect** — do not use the old `ref()` pattern for template refs: ```typescript // ❌ Old pattern const formRef = ref>(); ``` ### Setup script order The preferred order of a setup script in should be the following: ```typescript import { defineExpose } from '@vue/runtime-core'; // 1. Imports import { get, set } from '@vueuse/core'; // 2. Definitions (defineX) defineOptions({ inheritAttrs: false, }); const { msg } = defineProps<{ msg: string; }>(); const emit = defineEmits<{ 'update:msg': [msg: string]; }>(); // 3. I18n & vue-router const { t } = useI18n({ useScope: 'global' }); const router = useRouter(); const route = useRoute(); // 4. Reactive State variables const counter = ref(0); // 5. Use Pinia stores const { todos } = toRefs(useTodoStore()); // 6. Composables const { title } = useTitle(); // 7. Computed const titleNumber = computed(() => `${get(title)} ${get(counter)}`); // 8. Define Methods function increaseCounter(): void { set(counter, get(counter) + 1); } // 9. Watchers watch(title, (title) => { emit('update:msg', title); }); // 10. Lifecycle onMounted(() => { increaseCounter(); }); // 11. Exposed defineExpose({ increaseCounter, }); ``` ### Pinia Store For pinia stores the suggested order for elements is the following. ```typescript // stores/counter.ts import { defineStore } from 'pinia'; import { computed, ref } from 'vue'; export const useCounterStore = defineStore('counter', () => { // 1. State const count = ref(0); // 2. Getters const doubleCount = computed(() => count.value * 2); // 3. Actions function increment(): void { count.value++; } function decrement(): void { count.value--; } // 4. Watchers watch(count, (count) => { // do something }); return { count, doubleCount, increment, decrement, }; }); ``` ### useAttrs It should be only used if there is some access to the `attrs` inside the script tag. If the only usage is in the template part then use `$attrs` instead. ### Styling Use [Tailwind CSS](https://tailwindcss.com/) utility classes directly in the template for styling components. Avoid using scoped styles, CSS modules, or BEM naming conventions. ```vue ``` CSS modules (`