diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b0b0381..34b926fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,5 +64,8 @@ jobs: - name: Check anchors 🔗 run: pnpm run check:anchors + - name: Check app links 🔗 + run: pnpm run check:app-links + - name: Build run: pnpm run build diff --git a/package.json b/package.json index 8462d670..a7801097 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "lint": "eslint .", "check:images": "node scripts/check-images.mjs", "check:anchors": "node scripts/check-anchors.mjs", + "check:app-links": "node scripts/check-app-links.mjs", "lint-staged": "lint-staged", "prepare": "husky" }, diff --git a/public/images/_shared/create_account.webp b/public/images/_shared/create_account.webp index 8ed99859..2641146e 100644 Binary files a/public/images/_shared/create_account.webp and b/public/images/_shared/create_account.webp differ diff --git a/public/images/_shared/login_screen.webp b/public/images/_shared/login_screen.webp index cf7234cb..b36058a1 100644 Binary files a/public/images/_shared/login_screen.webp and b/public/images/_shared/login_screen.webp differ diff --git a/public/images/usage-guides/data-management/address-book/filter_bar.webp b/public/images/usage-guides/data-management/address-book/filter_bar.webp new file mode 100644 index 00000000..e02810ff Binary files /dev/null and b/public/images/usage-guides/data-management/address-book/filter_bar.webp differ diff --git a/public/images/usage-guides/data-management/assets/filter_ignored.webp b/public/images/usage-guides/data-management/assets/filter_ignored.webp index 65bdd355..15393bc6 100644 Binary files a/public/images/usage-guides/data-management/assets/filter_ignored.webp and b/public/images/usage-guides/data-management/assets/filter_ignored.webp differ diff --git a/public/images/usage-guides/data-management/prices/filter_bar.webp b/public/images/usage-guides/data-management/prices/filter_bar.webp new file mode 100644 index 00000000..94f1390f Binary files /dev/null and b/public/images/usage-guides/data-management/prices/filter_bar.webp differ diff --git a/public/images/usage-guides/history/events/action_picker.webp b/public/images/usage-guides/history/events/action_picker.webp new file mode 100644 index 00000000..6c0e0bac Binary files /dev/null and b/public/images/usage-guides/history/events/action_picker.webp differ diff --git a/public/images/usage-guides/history/events/asset_movement_form.webp b/public/images/usage-guides/history/events/asset_movement_form.webp index 6b5dd362..a975b453 100644 Binary files a/public/images/usage-guides/history/events/asset_movement_form.webp and b/public/images/usage-guides/history/events/asset_movement_form.webp differ diff --git a/public/images/usage-guides/history/events/bitcoin_event_form.webp b/public/images/usage-guides/history/events/bitcoin_event_form.webp new file mode 100644 index 00000000..e6d68c81 Binary files /dev/null and b/public/images/usage-guides/history/events/bitcoin_event_form.webp differ diff --git a/public/images/usage-guides/history/events/duplicate_custom.webp b/public/images/usage-guides/history/events/duplicate_custom.webp deleted file mode 100644 index 81edd08a..00000000 Binary files a/public/images/usage-guides/history/events/duplicate_custom.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/duplicate_custom_view.webp b/public/images/usage-guides/history/events/duplicate_custom_view.webp deleted file mode 100644 index 0e7d34db..00000000 Binary files a/public/images/usage-guides/history/events/duplicate_custom_view.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/eth_block_event_form.webp b/public/images/usage-guides/history/events/eth_block_event_form.webp index d55a0bec..2b257e42 100644 Binary files a/public/images/usage-guides/history/events/eth_block_event_form.webp and b/public/images/usage-guides/history/events/eth_block_event_form.webp differ diff --git a/public/images/usage-guides/history/events/eth_deposit_event_form.webp b/public/images/usage-guides/history/events/eth_deposit_event_form.webp index ab546485..370295a4 100644 Binary files a/public/images/usage-guides/history/events/eth_deposit_event_form.webp and b/public/images/usage-guides/history/events/eth_deposit_event_form.webp differ diff --git a/public/images/usage-guides/history/events/eth_withdrawal_event_form.webp b/public/images/usage-guides/history/events/eth_withdrawal_event_form.webp index 94152c63..849e9c57 100644 Binary files a/public/images/usage-guides/history/events/eth_withdrawal_event_form.webp and b/public/images/usage-guides/history/events/eth_withdrawal_event_form.webp differ diff --git a/public/images/usage-guides/history/events/evm_event_form.webp b/public/images/usage-guides/history/events/evm_event_form.webp index 0a74122e..4317c97e 100644 Binary files a/public/images/usage-guides/history/events/evm_event_form.webp and b/public/images/usage-guides/history/events/evm_event_form.webp differ diff --git a/public/images/usage-guides/history/events/evm_swap_event_form.webp b/public/images/usage-guides/history/events/evm_swap_event_form.webp index af0578a7..3348d612 100644 Binary files a/public/images/usage-guides/history/events/evm_swap_event_form.webp and b/public/images/usage-guides/history/events/evm_swap_event_form.webp differ diff --git a/public/images/usage-guides/history/events/history_event_form.webp b/public/images/usage-guides/history/events/history_event_form.webp index 9ce34e7e..16e21927 100644 Binary files a/public/images/usage-guides/history/events/history_event_form.webp and b/public/images/usage-guides/history/events/history_event_form.webp differ diff --git a/public/images/usage-guides/history/events/internal_tx_conflicts_banner.webp b/public/images/usage-guides/history/events/internal_tx_conflicts_banner.webp deleted file mode 100644 index dfaf04d9..00000000 Binary files a/public/images/usage-guides/history/events/internal_tx_conflicts_banner.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/internal_tx_conflicts_dialog.webp b/public/images/usage-guides/history/events/internal_tx_conflicts_dialog.webp deleted file mode 100644 index 425e9381..00000000 Binary files a/public/images/usage-guides/history/events/internal_tx_conflicts_dialog.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/internal_tx_conflicts_dialog_failed.webp b/public/images/usage-guides/history/events/internal_tx_conflicts_dialog_failed.webp deleted file mode 100644 index 26504e52..00000000 Binary files a/public/images/usage-guides/history/events/internal_tx_conflicts_dialog_failed.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/internal_tx_conflicts_dialog_settings.webp b/public/images/usage-guides/history/events/internal_tx_conflicts_dialog_settings.webp deleted file mode 100644 index 563cf56b..00000000 Binary files a/public/images/usage-guides/history/events/internal_tx_conflicts_dialog_settings.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/internal_tx_conflicts_general_settings.webp b/public/images/usage-guides/history/events/internal_tx_conflicts_general_settings.webp deleted file mode 100644 index 2266e49e..00000000 Binary files a/public/images/usage-guides/history/events/internal_tx_conflicts_general_settings.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/internal_tx_conflicts_menu.webp b/public/images/usage-guides/history/events/internal_tx_conflicts_menu.webp deleted file mode 100644 index 8bac599d..00000000 Binary files a/public/images/usage-guides/history/events/internal_tx_conflicts_menu.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/internal_tx_conflicts_pinned.webp b/public/images/usage-guides/history/events/internal_tx_conflicts_pinned.webp deleted file mode 100644 index d14fd248..00000000 Binary files a/public/images/usage-guides/history/events/internal_tx_conflicts_pinned.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/issue_check_button.webp b/public/images/usage-guides/history/events/issue_check_button.webp deleted file mode 100644 index e9ccd4d1..00000000 Binary files a/public/images/usage-guides/history/events/issue_check_button.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/solana_event_form.webp b/public/images/usage-guides/history/events/solana_event_form.webp new file mode 100644 index 00000000..e0380c59 Binary files /dev/null and b/public/images/usage-guides/history/events/solana_event_form.webp differ diff --git a/public/images/usage-guides/history/events/solana_swap_event_form.webp b/public/images/usage-guides/history/events/solana_swap_event_form.webp new file mode 100644 index 00000000..4526e3c4 Binary files /dev/null and b/public/images/usage-guides/history/events/solana_swap_event_form.webp differ diff --git a/public/images/usage-guides/history/events/swap_event_form.webp b/public/images/usage-guides/history/events/swap_event_form.webp index 7fc72856..18b3b027 100644 Binary files a/public/images/usage-guides/history/events/swap_event_form.webp and b/public/images/usage-guides/history/events/swap_event_form.webp differ diff --git a/public/images/usage-guides/history/events/unmatched_asset_movements.webp b/public/images/usage-guides/history/events/unmatched_asset_movements.webp deleted file mode 100644 index 1db40ba2..00000000 Binary files a/public/images/usage-guides/history/events/unmatched_asset_movements.webp and /dev/null differ diff --git a/public/images/usage-guides/history/events/unmatched_asset_movements_potential.webp b/public/images/usage-guides/history/events/unmatched_asset_movements_potential.webp deleted file mode 100644 index 9522bd80..00000000 Binary files a/public/images/usage-guides/history/events/unmatched_asset_movements_potential.webp and /dev/null differ diff --git a/public/images/usage-guides/history/issues/actions_center.webp b/public/images/usage-guides/history/issues/actions_center.webp new file mode 100644 index 00000000..23e93b46 Binary files /dev/null and b/public/images/usage-guides/history/issues/actions_center.webp differ diff --git a/public/images/usage-guides/history/issues/duplicate_custom_view.webp b/public/images/usage-guides/history/issues/duplicate_custom_view.webp new file mode 100644 index 00000000..99e31b21 Binary files /dev/null and b/public/images/usage-guides/history/issues/duplicate_custom_view.webp differ diff --git a/public/images/usage-guides/history/issues/internal_tx_conflicts_dialog.webp b/public/images/usage-guides/history/issues/internal_tx_conflicts_dialog.webp new file mode 100644 index 00000000..c8e1ef4e Binary files /dev/null and b/public/images/usage-guides/history/issues/internal_tx_conflicts_dialog.webp differ diff --git a/public/images/usage-guides/history/issues/internal_tx_conflicts_dialog_failed.webp b/public/images/usage-guides/history/issues/internal_tx_conflicts_dialog_failed.webp new file mode 100644 index 00000000..02930d7d Binary files /dev/null and b/public/images/usage-guides/history/issues/internal_tx_conflicts_dialog_failed.webp differ diff --git a/public/images/usage-guides/history/issues/internal_tx_conflicts_dialog_settings.webp b/public/images/usage-guides/history/issues/internal_tx_conflicts_dialog_settings.webp new file mode 100644 index 00000000..9ea3797d Binary files /dev/null and b/public/images/usage-guides/history/issues/internal_tx_conflicts_dialog_settings.webp differ diff --git a/public/images/usage-guides/history/issues/internal_tx_conflicts_general_settings.webp b/public/images/usage-guides/history/issues/internal_tx_conflicts_general_settings.webp new file mode 100644 index 00000000..0e4e7735 Binary files /dev/null and b/public/images/usage-guides/history/issues/internal_tx_conflicts_general_settings.webp differ diff --git a/public/images/usage-guides/history/issues/internal_tx_conflicts_pinned.webp b/public/images/usage-guides/history/issues/internal_tx_conflicts_pinned.webp new file mode 100644 index 00000000..1e4cbeae Binary files /dev/null and b/public/images/usage-guides/history/issues/internal_tx_conflicts_pinned.webp differ diff --git a/public/images/usage-guides/history/issues/issue_check_button.webp b/public/images/usage-guides/history/issues/issue_check_button.webp new file mode 100644 index 00000000..279a45ab Binary files /dev/null and b/public/images/usage-guides/history/issues/issue_check_button.webp differ diff --git a/public/images/usage-guides/history/issues/unmatched_asset_movements.webp b/public/images/usage-guides/history/issues/unmatched_asset_movements.webp new file mode 100644 index 00000000..de08aea8 Binary files /dev/null and b/public/images/usage-guides/history/issues/unmatched_asset_movements.webp differ diff --git a/public/images/usage-guides/history/issues/unmatched_asset_movements_potential.webp b/public/images/usage-guides/history/issues/unmatched_asset_movements_potential.webp new file mode 100644 index 00000000..0e6412b5 Binary files /dev/null and b/public/images/usage-guides/history/issues/unmatched_asset_movements_potential.webp differ diff --git a/public/images/usage-guides/portfolio/accounts/aggregated_view_per_chain.webp b/public/images/usage-guides/portfolio/accounts/aggregated_view_per_chain.webp index 6f30675d..900aa76c 100644 Binary files a/public/images/usage-guides/portfolio/accounts/aggregated_view_per_chain.webp and b/public/images/usage-guides/portfolio/accounts/aggregated_view_per_chain.webp differ diff --git a/public/images/usage-guides/portfolio/accounts/filter_chains.webp b/public/images/usage-guides/portfolio/accounts/filter_chains.webp index a33f1cc8..4e8a5856 100644 Binary files a/public/images/usage-guides/portfolio/accounts/filter_chains.webp and b/public/images/usage-guides/portfolio/accounts/filter_chains.webp differ diff --git a/public/images/usage-guides/portfolio/balances/filter_by_tag.webp b/public/images/usage-guides/portfolio/balances/filter_by_tag.webp index 07a14b9a..fa1892d8 100644 Binary files a/public/images/usage-guides/portfolio/balances/filter_by_tag.webp and b/public/images/usage-guides/portfolio/balances/filter_by_tag.webp differ diff --git a/public/images/usage-guides/settings/blockchain/indexer_notifications.webp b/public/images/usage-guides/settings/blockchain/indexer_notifications.webp new file mode 100644 index 00000000..bedec63a Binary files /dev/null and b/public/images/usage-guides/settings/blockchain/indexer_notifications.webp differ diff --git a/public/images/usage-guides/settings/interface/alias_priority.webp b/public/images/usage-guides/settings/interface/alias_priority.webp new file mode 100644 index 00000000..8929b9fd Binary files /dev/null and b/public/images/usage-guides/settings/interface/alias_priority.webp differ diff --git a/public/images/usage-guides/tax-accounting/accounting-rules/filter_bar.webp b/public/images/usage-guides/tax-accounting/accounting-rules/filter_bar.webp new file mode 100644 index 00000000..8e6ae9e6 Binary files /dev/null and b/public/images/usage-guides/tax-accounting/accounting-rules/filter_bar.webp differ diff --git a/public/images/usage-guides/tax-accounting/accounting-rules/matching_events.webp b/public/images/usage-guides/tax-accounting/accounting-rules/matching_events.webp new file mode 100644 index 00000000..46a23211 Binary files /dev/null and b/public/images/usage-guides/tax-accounting/accounting-rules/matching_events.webp differ diff --git a/public/images/usage-guides/utilities/help/support_menu.webp b/public/images/usage-guides/utilities/help/support_menu.webp index 6b29b041..29dccbd0 100644 Binary files a/public/images/usage-guides/utilities/help/support_menu.webp and b/public/images/usage-guides/utilities/help/support_menu.webp differ diff --git a/public/images/usage-guides/utilities/index/notifications.webp b/public/images/usage-guides/utilities/index/notifications.webp new file mode 100644 index 00000000..530e821f Binary files /dev/null and b/public/images/usage-guides/utilities/index/notifications.webp differ diff --git a/public/images/usage-guides/utilities/index/notifications_silence.webp b/public/images/usage-guides/utilities/index/notifications_silence.webp new file mode 100644 index 00000000..4e1c5073 Binary files /dev/null and b/public/images/usage-guides/utilities/index/notifications_silence.webp differ diff --git a/scripts/check-anchors.mjs b/scripts/check-anchors.mjs index 1b8c68ec..a303aea4 100644 --- a/scripts/check-anchors.mjs +++ b/scripts/check-anchors.mjs @@ -16,6 +16,12 @@ import process from 'node:process'; const ROOT = resolve(import.meta.dirname, '..'); const SKIP_DIRS = new Set(['node_modules', '.git', '.vitepress', 'dist', 'cache', 'scripts', 'public']); +/** + * Never published, so they are neither a link source nor an anchor target. + * Mirrors `srcExclude` in `.vitepress/config.mts` — keep the two in step. + */ +const SKIP_FILES = new Set(['README.md', 'LICENSE.md']); + /** A markdown link to an internal page with an anchor: `](/some/page#the-anchor)`. */ const ANCHORED_LINK = /]\(\/([\w/-]+)#([\w-]+)\)/g; @@ -43,7 +49,7 @@ async function walk(dir) { continue; found.push(...await walk(join(dir, entry.name))); } - else if (entry.name.endsWith('.md')) { + else if (!SKIP_FILES.has(entry.name) && entry.name.endsWith('.md')) { found.push(join(dir, entry.name)); } } diff --git a/scripts/check-app-links.mjs b/scripts/check-app-links.mjs new file mode 100644 index 00000000..220d8022 --- /dev/null +++ b/scripts/check-app-links.mjs @@ -0,0 +1,103 @@ +/** + * The app deep-links into these docs. Renaming a heading or moving a page silently breaks a link + * inside rotki itself, and nothing in this repo would notice: `check-anchors.mjs` only validates + * links written in the docs, and VitePress never sees the app at all. + * + * The list mirrors `externalLinks` in `frontend/app/shared/external-links.ts`. It has to be + * maintained by hand, because the app is a different repository. When a link here fails, fix the + * docs rather than this list: the app is already released and cannot be changed retroactively. + * + * Only links into this site are listed. Third-party URLs and the old readthedocs changelog are the + * app's problem, not ours. + */ + +import { readdir, readFile } from 'node:fs/promises'; +import { join, relative, resolve } from 'node:path'; +import process from 'node:process'; + +const ROOT = resolve(import.meta.dirname, '..'); +const SKIP_DIRS = new Set(['node_modules', '.git', '.vitepress', 'dist', 'cache', 'scripts', 'public', 'screenshots']); +const SKIP_FILES = new Set(['README.md', 'LICENSE.md']); + +/** `page path` -> anchors the app links to. An empty array means the app only links to the page. */ +const APP_LINKS = { + 'contribution-guides/contribute-as-developer': [ + 'get-coingecko-asset-identifier', + 'get-cryptocompare-asset-identifier', + 'add-a-new-language-or-translation', + ], + 'faq': [], + 'premium/devices': [], + 'requirement-and-installation/docker': ['session-authentication'], + 'usage-guides/data-management/address-book': ['importing-address-book-names-csv'], + 'usage-guides/integrations/exchange-keys': ['exchanges-api-keys'], + 'usage-guides/integrations/external-services': ['the-graph', 'gnosis-pay'], + 'usage-guides/portfolio/accounts': ['import-and-export-blockchain-accounts-csv'], + 'usage-guides/tax-accounting/accounting-rules': [ + 'count-cost-basis-pnl', + 'accounting-treatment-swap', + 'accounting-treatment-basis-transfer', + ], + 'usage-guides/tax-accounting/event-types': [], +}; + +const HEADING = /^#{1,6} +(.+?)\s*$/gm; + +/** Matches VitePress: lowercase, collapse every run of non-alphanumerics into one hyphen. */ +function slug(heading) { + return heading + .replace(/`/g, '') + .toLowerCase() + .replace(/[^\da-z]+/g, '-') + .replace(/^-|-$/g, ''); +} + +async function walk(dir) { + const found = []; + for (const entry of await readdir(dir, { withFileTypes: true })) { + if (entry.isDirectory()) { + if (!SKIP_DIRS.has(entry.name)) + found.push(...await walk(join(dir, entry.name))); + } + else if (entry.name.endsWith('.md') && !SKIP_FILES.has(entry.name)) { + found.push(join(dir, entry.name)); + } + } + return found; +} + +async function main() { + const files = await walk(ROOT); + const pages = new Map(); + for (const file of files) { + const path = relative(ROOT, file).split('\\').join('/').replace(/\.md$/, ''); + pages.set(path, await readFile(file, 'utf8')); + } + + const errors = []; + for (const [path, anchors] of Object.entries(APP_LINKS)) { + const text = pages.get(path) ?? pages.get(`${path}/index`); + if (text === undefined) { + errors.push(`the app links to a page that does not exist: /${path}\n restore it, or add a redirect — the released app cannot be changed`); + continue; + } + + const headings = new Set([...text.matchAll(HEADING)].map(match => slug(match[1]))); + for (const anchor of anchors) { + if (!headings.has(anchor)) + errors.push(`the app links to a heading that does not exist: /${path}#${anchor}\n a heading on that page must slug to "${anchor}"`); + } + } + + if (errors.length > 0) { + console.error(`\n${errors.length} broken app link${errors.length === 1 ? '' : 's'} found:\n`); + for (const error of errors) + console.error(` ✖ ${error}\n`); + process.exit(1); + } + + const total = Object.values(APP_LINKS).reduce((sum, anchors) => sum + Math.max(anchors.length, 1), 0); + console.log(`✔ all ${total} links the app makes into these docs resolve`); +} + +await main(); diff --git a/scripts/check-images.mjs b/scripts/check-images.mjs index 62c2e737..85a7a1ed 100644 --- a/scripts/check-images.mjs +++ b/scripts/check-images.mjs @@ -27,6 +27,12 @@ const SHARED_DIRS = new Set(['_shared', '_external']); */ const SKIP_DIRS = new Set(['node_modules', '.git', '.vitepress', 'dist', 'cache', 'scripts']); +/** + * Never published, so their prose is not a page and its `/images/...` mentions are not references. + * Mirrors `srcExclude` in `.vitepress/config.mts` — keep the two in step. + */ +const SKIP_FILES = new Set(['README.md', 'LICENSE.md']); + /** Files that can carry an image reference. */ const TEXT_EXTENSIONS = new Set(['.md', '.vue', '.ts', '.mts', '.js', '.mjs', '.json']); @@ -38,7 +44,7 @@ async function walk(dir, predicate) { continue; found.push(...await walk(join(dir, entry.name), predicate)); } - else if (predicate(entry.name)) { + else if (!SKIP_FILES.has(entry.name) && predicate(entry.name)) { found.push(join(dir, entry.name)); } } @@ -119,6 +125,39 @@ function misplacedImages(imageFiles, docPages) { .map(([image, orphanDir]) => `image is not under a docs page: public/images/${image}\n "${orphanDir}" is not a docs page — move it under its page's directory, or into _shared/ if several pages use it`); } +/** + * The image sits under a real docs page, but a *different* page is the one referencing it. That + * passes the placement check above and still breaks the convention, because `ls ` no + * longer answers "which images does this page own". + * + * Only single-referrer images are judged. An image used by several pages belongs in `_shared/`, + * which is what the placement check already says, so flagging it here would just duplicate that. + */ +function strandedImages(references, docPages) { + const errors = []; + for (const [reference, sources] of references) { + const image = reference.replace(/^\/images\//, ''); + const parts = image.split('/'); + const dir = parts.slice(0, -1).join('/'); + + if (dir === '' || SHARED_DIRS.has(parts[0]) || !docPages.has(dir)) + continue; + + const pages = new Set([...sources].map(source => + relative(ROOT, source).split('\\').join('/').replace(/\.md$/, ''), + )); + + if (pages.size !== 1) + continue; + + const [only] = pages; + if (only !== dir) { + errors.push(`image sits under another page's directory: public/images/${image}\n only ${only}.md references it — move it to public/images/${only}/`); + } + } + return errors; +} + async function main() { const imageFiles = (await walk(IMAGES_DIR, () => true)) .map(file => relative(IMAGES_DIR, file).split('\\').join('/')); @@ -135,6 +174,7 @@ async function main() { ...brokenReferences(references, imageFiles), ...unreferencedImages(imageFiles, referenced), ...misplacedImages(imageFiles, docPages), + ...strandedImages(references, docPages), ]; if (errors.length > 0) { diff --git a/usage-guides/data-management/address-book.md b/usage-guides/data-management/address-book.md index 00bafb40..cb0779e6 100644 --- a/usage-guides/data-management/address-book.md +++ b/usage-guides/data-management/address-book.md @@ -28,8 +28,10 @@ rotki provides an address book for blockchains. This replaces addresses with nam The address book uses the same filter bar as the rest of rotki, with a pill for `Address`, `Name` and `Chain`. Chains are shown with their logo and name and picked from a list. There is also a -`Strict chain` pill: with it added, only entries recorded for that exact chain are shown, rather than -also including entries that apply to every chain. +`Strict blockchain filter` pill: with it added, only entries recorded for that exact chain are shown, +rather than also including entries that apply to every chain. + +![Filtering the address book](/images/usage-guides/data-management/address-book/filter_bar.webp) Both the chain selector and the strict-chain checkbox used to sit beside the bar; they are pills inside it now, so there is a single place to filter from. See diff --git a/usage-guides/data-management/assets.md b/usage-guides/data-management/assets.md index 6c8d728d..67b6a297 100644 --- a/usage-guides/data-management/assets.md +++ b/usage-guides/data-management/assets.md @@ -155,7 +155,7 @@ To mark an asset as spam, navigate to `Manage Assets → Assets`, find the asset ## 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` by adding the `Ignored assets` pill to the filter bar and setting it to `Only show ignored assets`. A problem with automatic algorithms marking something as spam is that mistakes can be made and a legit token may be ignored. +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` by adding the `Ignored assets` pill to the filter bar and setting it to `Only ignored`, which also shows how many there are. 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/usage-guides/data-management/assets/filter_ignored.webp) diff --git a/usage-guides/data-management/prices.md b/usage-guides/data-management/prices.md index 5537c8ef..975cb142 100644 --- a/usage-guides/data-management/prices.md +++ b/usage-guides/data-management/prices.md @@ -27,13 +27,16 @@ The `Oracle Prices` page has two tabs: ![Oracle prices listing](/images/usage-guides/data-management/prices/oracle_list.webp) -The **Prices** tab uses the same filter bar as the rest of rotki, with a pill for the `From asset`, -the `To asset`, the `Source` oracle and the `Period`. Assets are shown with their icon and symbol, -and each oracle by the name the table itself uses rather than its raw identifier. The two separate -start and end date filters are now one period pill with a date picker for each end. See +The **Prices** tab uses the same filter bar as the rest of rotki, with a pill for the `Source asset`, +the `Target asset`, the `Source` oracle and the `Period`. Those first two filter the `From Asset` and +`To Asset` columns. Assets are shown with their icon and symbol, and each oracle by the name the +table itself uses rather than its raw identifier. The two separate start and end date filters are now +one period pill with a date picker for each end. See [Filtering history events](/usage-guides/history/filtering) for the shared syntax and keyboard handling. +![Filtering cached oracle prices](/images/usage-guides/data-management/prices/filter_bar.webp) + Each row in the **Prices** tab can be edited or deleted. Use this when you know the cached price is wrong (for example, an oracle returned a stale or incorrect value) and want to override it without adding a separate manual entry. Deleting an entry removes the cached value entirely; the next lookup will hit the oracle again. Click the edit icon on a row to open the edit dialog: diff --git a/usage-guides/history/events.md b/usage-guides/history/events.md index a27b3bdf..e1ce98d2 100644 --- a/usage-guides/history/events.md +++ b/usage-guides/history/events.md @@ -256,6 +256,8 @@ You can add multiple `spend` and `receive` assets. == Bitcoin Event +![Bitcoin event form](/images/usage-guides/history/events/bitcoin_event_form.webp) + Use this entry type for a decoded Bitcoin or Bitcoin Cash transaction event. The form automatically uses `BTC` for Bitcoin and `BCH` for Bitcoin Cash, so the asset cannot be changed independently. The key fields are `Transaction ID` (the transaction hash), `Location` (Bitcoin or Bitcoin Cash), `Timestamp`, `Amount`, `Action`, `Sequence Index`, and `Counterparty`. An amount is required. Location and transaction ID are fixed after creation. @@ -268,24 +270,27 @@ Advanced options include `Group Identifier` and `Extra Data` for additional cont == Solana Event +![Solana event form](/images/usage-guides/history/events/solana_event_form.webp) + 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). - `Action`: The same action picker 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 +![Solana swap event form](/images/usage-guides/history/events/solana_swap_event_form.webp) + 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. +- `Contract Address`: The Solana program or contract address involved. - `Sequence Index` / `Counterparty`: Same as other event types. ::: @@ -297,6 +302,8 @@ Every event form has one `Action` field describing what the event does, written as a raw type and subtype pair. Open it and you get a searchable list, so you can type `bridge` or `airdrop` instead of working out which combination expresses it. +![The action picker](/images/usage-guides/history/events/action_picker.webp) + Actions are grouped by intent: `Trade`, `Transfer`, `DeFi deposit & withdraw`, `DeFi borrow & repay`, `Staking`, `Income`, `Expense`, `Donation`, `NFT`, `Bridge`, `Centralized exchange`, `Validator`, `Governance`, `Approval`, `Loss` and `Other`. Each row carries a one-line description of what it diff --git a/usage-guides/history/issues.md b/usage-guides/history/issues.md index 0acb2e9b..9bc3a851 100644 --- a/usage-guides/history/issues.md +++ b/usage-guides/history/issues.md @@ -9,7 +9,7 @@ rotki can detect certain issues with your history events that may affect account the **categories** that need attention, not the individual items, so a badge of `2` means two kinds of thing to deal with, however many events each covers. -![Issue check button](/images/usage-guides/history/events/issue_check_button.webp) +![Issue check button](/images/usage-guides/history/issues/issue_check_button.webp) Opening it lists every category as a row with its own count, a short description and its own action button. Categories with nothing to do are listed too, so you can re-check them at any time rather @@ -17,19 +17,30 @@ than wondering whether they were ever looked at. Rows are ordered by what you ca needing attention first, then ones where only ignored items remain, then any locked behind a premium tier. +![The actions center](/images/usage-guides/history/issues/actions_center.webp) + The categories are: -| Category | What it means | -| ---------------------------------- | -------------------------------------------------------------------------------------- | -| **Tracked accounts** | You are not tracking any accounts yet, so every other count below is legitimately zero | -| **Unmatched asset movements** | An exchange deposit or withdrawal not yet linked to its on-chain transaction | -| **Unmatched bridge transactions** | A bridge leg not yet linked to its counterpart on the other chain | -| **Duplicate events** | Duplicated customized events that can be fixed automatically | -| **Duplicates needing review** | Duplicated customized events that need you to choose | -| **Internal transaction conflicts** | A re-pulled internal transaction disagrees with what was stored | -| **Undecoded transactions** | Transactions queried but not yet decoded into events | +| Category | What it means | Action | +| ---------------------------------- | -------------------------------------------------------------------------------------- | ---------------- | +| **Tracked accounts** | You are not tracking any accounts yet, so every other count below is legitimately zero | `Add an account` | +| **Unmatched asset movements** | An exchange deposit or withdrawal not yet linked to its on-chain transaction | `Match` ᴾ | +| **Unmatched bridge transactions** | A bridge leg not yet linked to its counterpart on the other chain | `Match` ᴾ | +| **Duplicate events** | Duplicated customized events that can be fixed automatically | `Review` | +| **Duplicates needing review** | Duplicated customized events that need you to choose | `Review` | +| **Internal transaction conflicts** | A re-pulled internal transaction disagrees with what was stored | `Review` | +| **Undecoded transactions** | Transactions queried but not yet decoded into events | `View status` | + +ᴾ Premium only. A locked row still appears in the list, but it never raises the badge, so the count +on the button reflects what you can actually act on. + +Two of these mean less than they look. **Tracked accounts** and **Undecoded transactions** describe +the state of your data rather than a mistake to correct: the first is only ever raised on an empty +account, and the second clears itself as decoding proceeds. The remaining five are the ones that +affect accounting, and each is covered in its own section below. -The ones needing an explanation of their own are covered below. +When every item in a category has been ignored rather than resolved, the row stays in the list but +its action changes to `Review ignored`, so ignoring something never makes it disappear silently. ## Unmatched Asset Movements @@ -51,7 +62,7 @@ This can happen when: ### How to resolve -![Match asset movements dialog](/images/usage-guides/history/events/unmatched_asset_movements.webp) +![Match asset movements dialog](/images/usage-guides/history/issues/unmatched_asset_movements.webp) You have several options to resolve unmatched asset movements: @@ -62,9 +73,16 @@ You have several options to resolve unmatched asset movements: - **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 are displayed in a list. Where one candidate stands out, it is marked as + **recommended** with a thumbs-up; when nothing qualifies, the list is simply the candidates that + fit the criteria. 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/usage-guides/history/events/unmatched_asset_movements_potential.webp) + If nothing comes back, the dialog says so and offers `Widen search`, which relaxes the two + criteria for you. You can also edit them directly and search again. + + ![Potential matches dialog](/images/usage-guides/history/issues/unmatched_asset_movements_potential.webp) 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. @@ -87,9 +105,9 @@ 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/usage-guides/history/events/duplicate_custom.webp) +Each type is its own row in the actions center, reached from the `Actions needed` button described +above: **Duplicate events** for the auto-fixable ones and **Duplicates needing review** for the rest, +each with its own count and its own `Review` action. ### How to resolve @@ -99,7 +117,7 @@ When duplicates are detected, an alert banner will appear showing the count for 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/usage-guides/history/events/duplicate_custom_view.webp) + ![Duplicate events in history view](/images/usage-guides/history/issues/duplicate_custom_view.webp) ## Internal Transaction Conflicts @@ -113,23 +131,24 @@ Internal transaction conflicts occur when rotki detects inconsistencies in inter > [!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. +When conflicts are detected they appear as the **Internal transaction conflicts** row in the actions +center, with the number needing attention and a `Review` action that opens the dialog below. -![Internal transaction conflicts banner](/images/usage-guides/history/events/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/usage-guides/history/events/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: +Click `Review` on that row 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/usage-guides/history/events/internal_tx_conflicts_dialog.webp) +![Internal transaction conflicts dialog](/images/usage-guides/history/issues/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. -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. +The list uses the same filter bar as the rest of rotki, with a pill for `Chain` and one for `Date`. +`Chain` takes a single chain and offers EVM chains only, and `Date` folds both ends of the range into +one pill. The Pending, Failed and Fixed tabs set the status, so it is not a pill. See +[Filtering history events](/usage-guides/history/filtering) for the shared syntax and keyboard +handling. ### How to resolve @@ -146,7 +165,7 @@ Each conflict shows the transaction hash, chain, action type (repull or fix & re 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/usage-guides/history/events/internal_tx_conflicts_dialog_failed.webp) +![Internal transaction conflicts failed tab](/images/usage-guides/history/issues/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. @@ -154,7 +173,7 @@ You can retry failed conflicts at any time by selecting them and clicking `Resol 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/usage-guides/history/events/internal_tx_conflicts_pinned.webp) +![Internal transaction conflicts pinned sidebar](/images/usage-guides/history/issues/internal_tx_conflicts_pinned.webp) ### Show in history events @@ -164,13 +183,15 @@ Click the external link icon on a conflict to highlight the corresponding transa You can configure the automatic conflict resolution behavior by clicking the gear icon in the dialog header. -![Internal transaction conflicts settings](/images/usage-guides/history/events/internal_tx_conflicts_dialog_settings.webp) +![Internal transaction conflicts settings](/images/usage-guides/history/issues/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). +- **Transactions per batch** - The number of conflicts to process per periodic task run (default: 100, minimum: 1). +- **Repull frequency (minutes)** - How often the system automatically attempts to resolve conflicts (default: 15 minutes, minimum: 0.5 minutes). -These settings are also available in `Settings > General > History Events`. +These settings are also available in `Settings > General > History Events`, where the same two +controls are titled `Internal transactions to repull` and `Conflict repull frequency`. The fields +themselves keep the labels above, so the values you see there are the same ones. -![Internal transaction conflicts in general settings](/images/usage-guides/history/events/internal_tx_conflicts_general_settings.webp) +![Internal transaction conflicts in general settings](/images/usage-guides/history/issues/internal_tx_conflicts_general_settings.webp) diff --git a/usage-guides/portfolio/balances.md b/usage-guides/portfolio/balances.md index ce6b9a5c..e37d35fd 100644 --- a/usage-guides/portfolio/balances.md +++ b/usage-guides/portfolio/balances.md @@ -75,7 +75,7 @@ This will enable image rendering of only whitelisted NFT domains. You can filter the tables by a combination of tags. -![Filter the accounts by tag](/images/usage-guides/portfolio/balances/filter_by_tag.webp) +![Filter a balances table by tag](/images/usage-guides/portfolio/balances/filter_by_tag.webp) Add the `Tags` pill to the filter bar above the table and pick the tags you want. Each tag is drawn in the colours you gave it, so a set of tag filters is readable at a glance. Removing the pill clears the diff --git a/usage-guides/settings/blockchain.md b/usage-guides/settings/blockchain.md index 52ebab47..2c2423fc 100644 --- a/usage-guides/settings/blockchain.md +++ b/usage-guides/settings/blockchain.md @@ -71,6 +71,8 @@ confirm, and rotki stops raising it for that chain. Suppressed chains are listed under **Suppressed "No indexers available" notifications** on this page. Remove a chain from that list to start showing its notification again. +![Suppressed indexer notifications](/images/usage-guides/settings/blockchain/indexer_notifications.webp) + Suppression is per chain, so silencing one never silences another. Even without suppressing anything, a notification you keep ignoring backs off on its own — see [how often a notification repeats](/usage-guides/utilities/#how-often-a-notification-repeats). diff --git a/usage-guides/settings/interface.md b/usage-guides/settings/interface.md index 6815f2bb..70d598ad 100644 --- a/usage-guides/settings/interface.md +++ b/usage-guides/settings/interface.md @@ -56,9 +56,17 @@ Configure whether the graph y-axis starts at 0 or the minimum amount for the per ### Alias Name for Addresses -Enable or disable alias names for blockchain addresses, and change the order the sources are resolved in. The sources are `Private address book`, `Global address book`, `ENS names`, `GNS names (.gwei)`, `Ethereum tokens`, `Hardcoded mappings` and `Blockchain account labels`. +Shown in the app as **Blockchain address aliases**. Enable or disable alias names for blockchain +addresses, and change the order the sources are resolved in. The first source that has a name for an +address wins. In priority order the defaults are `Private address book`, `Blockchain account labels`, +`Global address book`, `Ethereum tokens`, `Hardcoded mappings`, `ENS names` and `GNS names (.gwei)`. -`GNS names (.gwei)` is opt-in and off by default. Add it to the priority list to have [Gwei Name Service](https://gwei.domains) names shown for your addresses, positioned wherever you want relative to ENS. Avatars follow the same priority. +![The address alias priority list](/images/usage-guides/settings/interface/alias_priority.webp) + +`GNS names (.gwei)` was added in 1.44 and sits last by default, so a +[Gwei Name Service](https://gwei.domains) name is used only where nothing higher, ENS included, has +one. Drag it above `ENS names` to prefer it, or remove it from the list to ignore GNS entirely. +Avatars follow the same priority. ### Newly Detected Tokens diff --git a/usage-guides/tax-accounting/accounting-rules.md b/usage-guides/tax-accounting/accounting-rules.md index 50ada993..ff2dc5f5 100644 --- a/usage-guides/tax-accounting/accounting-rules.md +++ b/usage-guides/tax-accounting/accounting-rules.md @@ -184,14 +184,21 @@ A rule and the events it applies to are one click apart in either direction: - From an event, the [edit accounting rule](/usage-guides/history/events#edit-accounting-rule) action takes you to the rule that governs it. +![Events matching an accounting rule](/images/usage-guides/tax-accounting/accounting-rules/matching_events.webp) + +The pills carry the rule over, so you can widen or narrow the selection from there rather than +rebuilding the filter by hand. + ### Filtering the rules -The rules table uses the same filter bar as the rest of rotki, with a pill for `Event type`, -`Event subtype` and `Counterparty`. Types and subtypes are picked from a list and read as words -rather than as their raw values, and counterparties are shown with their protocol icon and name. See +The rules table uses the same filter bar as the rest of rotki, with a pill for `Type`, `Subtype` and +`Counterparty`. Types and subtypes are picked from a list and read as words rather than as their raw +values, and counterparties are shown with their protocol icon and name. See [Filtering history events](/usage-guides/history/filtering) for the shared syntax and keyboard handling. +![Filtering the accounting rules](/images/usage-guides/tax-accounting/accounting-rules/filter_bar.webp) + ### 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). diff --git a/usage-guides/utilities/help.md b/usage-guides/utilities/help.md index fa4f3b4a..cb6fa990 100644 --- a/usage-guides/utilities/help.md +++ b/usage-guides/utilities/help.md @@ -16,6 +16,10 @@ The Help & Support menu provides quick access to: - **Discord** - Join the community and get support - **Github** - Review the code and open issues - **Twitter / X** - Follow for updates + +When you run rotki in a browser, for example the docker deployment, two more entries appear at the +bottom of the menu. The desktop app does not show them here. + - **About** - Version information, including the data directory currently in use - **Browser Log** - Download the browser log file diff --git a/usage-guides/utilities/index.md b/usage-guides/utilities/index.md index 98a4d4d8..7d6d5345 100644 --- a/usage-guides/utilities/index.md +++ b/usage-guides/utilities/index.md @@ -35,8 +35,11 @@ You can also pin notes; the pinned notes will appear at the top. rotki reports what it is doing, and anything that needs your attention, through the **notification area** in the toolbar. Opening it shows every notification received this session, grouped into four -tabs: `View All`, `Error`, `Needs Action` and `Reminder`. Many notifications carry an action, such as -adding a missing API key or opening the dialog that resolves what they are about. +tabs: `View All`, `Needs Action`, `Reminder` and `Error`. Many notifications carry an action, such as +adding a missing API key or opening the dialog that resolves what they are about. Any task still +running is shown above the tabs, with its progress. + +![The notification area](/images/usage-guides/utilities/index/notifications.webp) Notifications also appear briefly as a **popup** in the corner of the window as they arrive. @@ -46,6 +49,8 @@ If the popups interrupt you, click **Silence notification popups** in the notifi button then reads `Popups silenced. Click to allow them again`, and you can turn them back on the same way. +![Silencing notification popups](/images/usage-guides/utilities/index/notifications_silence.webp) + Nothing is lost while popups are silenced. Every notification still arrives in the notification area with its actions intact; only the transient popup is suppressed. The setting is stored with your account, so it stays as you left it the next time you log in.