=== Sakurato Crypto Portfolio Tracker ===
Contributors: sakurato
Tags: bitcoin, crypto, portfolio, tracker, cryptocurrency
Requires at least: 5.8
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 4.3.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Track your crypto portfolio in WordPress: real-time prices, P&amp;L, ROI, transaction history, and email price alerts. No wallet needed.

== Description ==

Sakurato Crypto Portfolio Tracker is a WordPress plugin for tracking cryptocurrency portfolios directly inside your WordPress dashboard. Add buy, sell and withdrawal transactions, monitor real-time portfolio value, view profit/loss and ROI, analyze performance charts (24H, 7D, 30D, 60D, 180D, 1Y), track stablecoins, create email price alerts, and display selected portfolio data on the frontend with shortcodes.

**The plugin does not connect to your wallet or exchange accounts.** You manually add your transactions — the plugin then fetches public market prices from the CoinGecko API to calculate current portfolio value. No personal data is sent to external services.

Real-time prices are powered by the CoinGecko public API — no API key required, and over 13,000 coins and tokens are supported.

---

**▶ [Try the Live Preview](https://wordpress.org/plugins/sakurato-crypto-portfolio-tracker/?preview=1) — see the plugin in action before you install. No account required.**

---

**Features:**

* Single portfolio with full transaction history (buy / sell / withdraw)
* Real-time price updates via CoinGecko API (no API key required)
* Portfolio value and ROI calculations
* Performance charts (Chart.js — served locally, no CDN)
* Performance Periods dashboard (24H, 7D, 30D, 60D, 180D, 1Y, ALL) with sparklines
* Stablecoin tracking (USDT, USDC, DAI, and more)
* Admin dashboard with metrics overview
* Import / export portfolio data — JSON (full) and CSV (import and export)
* Portfolio snapshots
* Portfolio notes
* Shortcodes for frontend display (use the `sakurato_` prefix, e.g. `[sakurato_crypto_portfolio]`)
* Pie and ROI charts
* Holdings Distribution donut on dashboard (top 7 holdings + "Other")
* Social share widget for portfolio snapshots
* Price Alerts — email notifications for coin price, portfolio value, and portfolio P&L thresholds
* Alert recipient email setting with WordPress admin email fallback
* Dark mode support
* Responsive design

**Pro Add-on (optional)**

An optional **[Sakurato CPT Pro](https://sakurato.tech/)** add-on extends this free plugin with: unlimited multi-portfolio management, unlimited active Price Alerts, a full Reports module (Buy / Sell / Withdrawal / Tax Summary with filters and per-section charts), CSV export across all portfolios and per Reports section, and a premium donut chart for the dashboard. The free plugin is fully functional without any license key or upgrade.

== Installation ==

1. Upload the `crypto-portfolio-tracker` folder to the `/wp-content/plugins/` directory.
2. Activate the plugin through the **Plugins** menu in WordPress.
3. Navigate to **Crypto Portfolio** in the admin menu to get started.
4. Add your first cryptocurrency transaction and configure your portfolio settings.

== Frequently Asked Questions ==

= Does this plugin require an API key? =

No API key is required for the free CoinGecko tier. Optionally, you can enter a CoinGecko Demo or Pro API key in the settings for higher rate limits.

= How many portfolios can I track? =

The free plugin supports a single portfolio per user. For unlimited portfolios install the optional Sakurato CPT Pro add-on (https://sakurato.tech/).

= How many price alerts can I use? =

The free plugin supports one active coin price alert and one active portfolio alert. Portfolio alerts can watch either total portfolio value or portfolio P&L percentage. Sakurato CPT Pro unlocks unlimited active alerts.

= Who receives price alert emails? =

By default, alerts are sent to the WordPress administration email address. You can set a separate recipient in **Crypto Portfolio → Price Alerts → Email Notifications**.

= Which coins can I choose for coin price alerts? =

Coin price alerts use the coins currently held in your portfolio, so the selector stays focused and avoids duplicate CoinGecko entries.

= What cryptocurrencies are supported? =

All cryptocurrencies listed on CoinGecko are supported — that is over 13,000 coins and tokens.

= Can I import existing portfolio data? =

Yes. The plugin supports importing portfolio data from JSON and CSV files.

= Does the plugin use any external JavaScript libraries from a CDN? =

No. Chart.js is bundled with the plugin and served locally. No external CDN calls are made.

= What data does the plugin send to external services? =

Only coin identifiers (e.g. `bitcoin`, `ethereum`) are sent to the CoinGecko API to retrieve price data. No personal data or user information is transmitted. See the External Services section below for full details.

= Does the plugin connect to my crypto wallet or exchange account? =

No. The plugin does not connect to wallets or exchanges. You add transactions manually, and the plugin calculates your portfolio value using public market prices from CoinGecko.

= Is my portfolio data sent to any external server? =

No. Your portfolio transactions are stored in your WordPress database only. The plugin sends only coin identifiers (e.g. `bitcoin`) to the CoinGecko API to fetch public price data. No portfolio data, wallet addresses, or personal information is transmitted.

= Will this plugin slow down my website? =

No. Chart.js is bundled locally (no CDN). Price data is cached in a dedicated database table and refreshed in the background via WP-Cron — frontend visitors never wait for external API calls.

= Can I display my portfolio on the frontend? =

Yes. Use the provided shortcodes (e.g. `[sakurato_crypto_portfolio]`) to embed portfolio data on any page or post.

== Screenshots ==

1. Admin dashboard — portfolio value, Total/Unrealized/Realized P/L cards, ROI Performance chart, and Holdings Distribution donut chart.
2. Portfolio holdings table — coin list with quantities, average buy price, current price, cost basis, current value, and P/L per position.
3. Frontend shortcodes — Portfolio Value chart (Current Value vs Invested capital with P/L Zones toggle) and Portfolio ROI Performance chart embedded on any page.
4. API Settings — CoinGecko API key configuration, rate-limit tier selection, cache status, and troubleshooting panel.
5. Import & Export — backup portfolio data to JSON or CSV, and restore or migrate portfolios from a file.
6. Price Alerts — create coin price, portfolio value, and portfolio P&L email alerts with a configurable recipient.

== Changelog ==

= 4.3.1 =
* Fixed: Price Alerts table is now created automatically after updating from an older version, so alerts can be saved without reactivating the plugin
* Fixed: "Could not save the alert" error on sites upgraded via auto-update where the alerts table was missing

= 4.3.0 =
* Added: Price Alerts admin page with email notifications
* Added: Coin price alerts — notify when a currently held coin price goes above or below a USD threshold
* Added: Portfolio value alerts — notify when portfolio value goes above or below a threshold
* Added: Portfolio P&L percentage alerts — notify when total portfolio P&L crosses a percentage threshold
* Added: Alert recipient email setting with WordPress administration email fallback
* Added: Coin selector limited to current holdings to avoid duplicate or irrelevant CoinGecko entries
* Added: Hourly WP-Cron alert checks using the existing cached CoinGecko price layer
* Added: Free plan limits — one active coin alert and one active portfolio alert
* Added: Pro integration hook for unlimited active alerts via Sakurato CPT Pro
* Updated: Polish translation (pl_PL) — new Price Alerts strings translated

= 4.2.0 =
* Added: New "Calculators" tab with six handy crypto tools — Profit/Loss, Break-even, DCA average cost, a long-term DCA plan projection, portfolio allocation & rebalancing, and a live crypto/fiat converter
* Added: Profit/Loss calculator — see your gain or loss, ROI and fees for a single trade
* Added: Break-even calculator — find the exact sell price that gets your money back after fees, plus the price for a target profit
* Added: DCA Average — enter your past buys to find your real average cost per coin and unrealized profit/loss
* Added: DCA Plan — project how a recurring investment (with an optional starting amount) grows over years with compounding
* Added: Portfolio Allocation — enter your holdings and target weights to see exactly how much to buy or sell to rebalance
* Added: Converter — convert between crypto and USD / EUR / PLN at live market prices
* Note: the calculators run instantly in your browser; only the converter fetches live prices (from CoinGecko)
* Added: Break-even hint on the dashboard holdings table — hover a coin to see its break-even price and how far it is ("+X% needed to break even" or "in profit"); stablecoins excluded
* Added: Target Price (Investment Goals), available on the admin Portfolio Dashboard — a feature for the portfolio owner
* Added: "Target" column in the dashboard holdings table — set a per-coin goal inline; the input field itself doubles as a progress bar that fills (purple → amber → green) as price approaches the goal, with a "+X% needed" / "goal reached" hint
* Added: Portfolio Goal widget above the table — total portfolio value vs. target, progress bar, "+X% needed" and dollar amount to go, with a "goal reached" state
* Fixed: Target price hint now shows how much the price needs to rise to hit the goal (e.g. "+353% needed") instead of a misleading progress ratio
* Fixed: Stale date in Add / Sell / Withdraw forms — the date field now always defaults to today when the form opens (previously it could keep an old date if the page had been left open)
* Note: stablecoins are excluded from targets; full dark/light mode support
* Developer: added extension points so the Pro add-on can enhance the Allocation calculator — `sakurato_cpt_calc_alloc_toolbar` action, `sakurato_cpt_calc_portfolio_assets` filter, and a `window.sakuratoCptCalcAPI` JS hook (no visible change in the free plugin)
* Fixed: Untranslated header on the Portfolio Settings page — now properly wrapped for translation
* Added: About page — new feature cards for "Target Prices & Portfolio Goal" and "Crypto Calculators"
* Added: About page — Free plan list now mentions target prices and crypto calculators; Premium plan list now mentions "Load from portfolio" in the allocation calculator
* Updated: Polish translation (pl_PL) — new strings translated

= 4.1.1 =
* Changed: Default chart time range set to "All" on Performance and ROI % charts (was 1 month)
* Fixed: Donut chart legend contrast in light mode (#9ca3af → #6b7280)
* Fixed: Donut chart text colors no longer inherit from active WordPress theme (forced with !important, theme-aware hover/active)
* Added: Active legend item highlights with its segment color in the pie chart legend

= 4.1.0 =
* Fixed: Cron stampede — async price refresh now uses a 45-second transient lock so only one job is scheduled per batch, preventing 429 rate-limit errors from CoinGecko
* Fixed: PHP 8.1 deprecation warning (`strpos(null)`) — `cached_at` timestamp now stamped correctly on both sync and async price fetch paths
* Fixed: P/L Zones chart — red gradient now renders correctly for portfolios in loss (gradient was reversed, making the fill invisible)
* Added: "Create New Portfolio" import mode is now gated — free plugin shows Merge/Replace only; Sakurato CPT Pro unlocks the Create New option
* Fixed: Mobile responsive tables — All Transactions, Sales History, and Snapshots tables now scroll horizontally on ≤782px instead of collapsing to WP card layout
* Removed: `admin-reports.css` from free build (reports CSS belongs to Sakurato CPT Pro add-on)

= 4.0.0 =
* **BREAKING ARCHITECTURE CHANGE**: Plugin split into a free WP.org build and an optional Sakurato CPT Pro add-on. Existing multi-portfolio users must install the pro add-on (https://sakurato.tech/pro/) to keep using more than one portfolio
* Removed: Freemius SDK and the entire `freemius/` directory (~3.5 MB) — no third-party licensing code in the WP.org build
* Removed: Reports module (Buy / Sell / Withdrawal / Tax Summary, summary CSV export) — moved to the Sakurato CPT Pro add-on
* Removed: Multi-portfolio management page (Portfolio Manager submenu) — moved to the Sakurato CPT Pro add-on
* Removed: All upsell notices and dynamic upgrade URLs — replaced with a single static link to https://sakurato.tech/ on the About page
* Added: Native `uninstall.php` — clean removal of options, transients, cron events and database tables when the plugin is deleted
* Added: Extension hook `do_action( 'sakurato_cpt_admin_menu_after' )` — pro add-on registers Reports and Portfolio Manager submenus here
* Added: Extension hook `do_action( 'sakurato_cpt_dashboard_after_charts' )` — pro renders the Premium Donut Chart here
* Added: Extension hook `do_action( 'sakurato_cpt_export_handlers_init', $handler )` — pro registers CSV exporter and multi-portfolio exporter
* Added: Extension filter `apply_filters( 'sakurato_cpt_portfolio_limit', 1 )` — defaults to 1 in free, pro returns `PHP_INT_MAX`
* Added: `wp_add_privacy_policy_content()` — describes local-only data storage and CoinGecko coin-ID-only API requests

= 3.5.0 =
* **BREAKING**: All shortcode tags renamed with `sakurato_` prefix (e.g. `[crypto_portfolio]` → `[sakurato_crypto_portfolio]`, `[crypto_portfolio_chart]` → `[sakurato_crypto_portfolio_chart]`, etc.). Update existing pages — see Upgrade Notice below
* Compliance: Removed all in-plugin license checks and upgrade prompts (WP.org Guideline 5). The Reports page is fully accessible with no premium gate; multi-portfolio remains a single-portfolio design in the free build
* Fixed: CoinGecko Terms/Privacy URLs in readme corrected (removed `/en/` segment that failed SSL validation on WP.org)
* Fixed: Freemius SDK loading guarded with `function_exists( 'fs_dynamic_init' )` to prevent conflicts with other plugins bundling Freemius
* Security: Added `current_user_can( 'manage_options' )` capability checks to transaction delete and edit handlers
* Changed: All `wp_localize_script()` global JS variables now use the `sakuratoCpt*` prefix (`cptFrontend` → `sakuratoCptFrontend`, `cptDashboard` → `sakuratoCptDashboard`, `cptData` → `sakuratoCptData`, `cptExportImport` → `sakuratoCptExportImport`, `cptSocialData` → `sakuratoCptSocialData`)
* Changed: Admin page slugs renamed (`cpt-reports` → `sakurato-cpt-reports`, `cpt-about` → `sakurato-cpt-about`)
* Changed: Chart format settings sanitizer now whitelists allowed fields and clamps numeric values to safe ranges
* Removed: Premium upsell banner from the Reports page (full Reports summary visible to everyone)

= 3.4.0 =
* Added: Dashboard Performance Periods section with 7 time ranges (24H, 7D, 30D, 60D, 180D, 1Y, ALL) and sparklines
* Added: New `[crypto_portfolio_performance]` shortcode for embedded performance cards
* Added: `show_values` parameter for pie chart and performance chart shortcodes
* Fixed: Shortcode output now properly escaped with `esc_html()` (WP.org compliance)
* Fixed: `register_setting()` sanitizer updated with per-field validators (`sanitize_hex_color`, `absint`)
* Fixed: Nonce verification added to portfolio settings GET action
* Changed: Reports tab removed from free version (available in Premium add-on)
* Changed: Portfolio creation UI removed from free version (single-portfolio by design)
* Removed: All Freemius `is_paying()` feature-restriction checks from WP.org build

= 3.3.1 =
* Fixed: Freemius SDK set to `is_premium=false`, `is_org_compliant=true` for WordPress.org compliance
* Fixed: Replaced inline `<style>` injections in chart shortcodes with static CSS file + CSS custom properties on wrapper elements
* Fixed: Export CSV button and Reports section now correctly gated behind Premium license

= 3.3.0 =
* Performance: Price cache moved from wp_options (autoload=yes, 150-300 KB loaded on every WP request) to a dedicated database table `wp_cpt_price_cache`
* Performance: Stale-while-revalidate — frontend requests always return immediately from DB; background cron job refreshes stale coins asynchronously
* Performance: sleep() calls (rate-limit protection, 429 backoff) moved out of request path; they now execute only in background/cron context
* Improved: Atomic `INSERT ... ON DUPLICATE KEY UPDATE` upserts eliminate race conditions when multiple cron jobs run in parallel
* Improved: Filterable TTL values — override via `sakurato_cpt_price_cache_soft_ttl` (default 5 min), `_hard_ttl` (30 min), `_top_coins_list_ttl` (24 h) filters
* Fixed: Top coins list (`sakurato_cpt_top_500_coins_list`) now saved with `autoload=no`
* Compatibility: Existing installations automatically migrate old cache data on first update (idempotent migration)

= 3.2.0 =
* Added: Reports sections (Buy, Sell, Withdrawal, Tax Summary) are now a Premium feature — free users see a preview of up to 3 rows per section with a blur/lock overlay and upgrade prompt
* Updated: Upsell admin notice updated to highlight Reports access as a premium benefit alongside multiple portfolios
* Fixed: Withdrawal modal coin list failed to load due to an incorrect AJAX action name
* Fixed: Plugin Check compliance — SQL interpolation annotations, missing translators comments, direct DB query suppression

= 3.1.1 =
* Fix: Moved all inline style/script blocks to wp_add_inline_style() and wp_add_inline_script() for WP.org compliance
* Fix: Added wp_strip_all_tags() escaping for dynamic CSS output in shortcode chart styles
* Fix: Enqueued admin-inline.css for P/L cards, price cache indicator, and time filter styles

= 3.1.0 =
* Added: Reports tab — Buy Transactions, Sell Transactions, Withdrawals, and Tax Summary sections with year/month/portfolio filters
* Added: Per-section Chart.js charts (funding-source donut for buys, monthly bar for sells, destination donut for withdrawals)
* Added: Column sorting and pagination (10 rows/page) on all Reports tables
* Added: CSV export per section in Reports
* Added: 6 summary metric cards — Total Invested, Total Sold, Withdrawals, Net Capital Flow, Avg Buy Price, Avg Sell Price
* Added: Informational description in each Reports section explaining what data is shown
* Added: Download PNG button in Social Share widget (canvas-based, no server dependency)
* Added: Snapshots Management page now includes portfolio selector and info bar
* Added: Shortcode Generator expanded with 19 new parameters and dynamic show/hide per shortcode type
* Improved: CSS isolation for all shortcodes — styles no longer affected by the active WordPress theme
* Improved: Pie chart vertical layout — tighter padding, legend fills full width, full coin name hidden
* Improved: Admin menu order: Dashboard → Transactions → Snapshots → Portfolios → Shortcodes → Import/Export → API → About
* Improved: Reports mobile layout — tables scroll horizontally; less critical columns hidden on small screens
* Fixed: Sales History excluded internal portfolio swaps (USDT → Internal) — only real asset sales shown
* Fixed: Buy History excluded companion stablecoin entries from sales (Sale_proceeds payment source)
* Fixed: Monthly Sell chart totals excluded internal swaps
* Fixed: Tax Summary now groups by coin ID — same asset with different symbols (BTC / BITCOIN) appears as one row
* Fixed: Tax Summary Withdrawals column was always $0 — now correctly sums withdrawal values
* Fixed: Total Transactions metric and section badge counts show actual transaction count, not grouped row count
* Fixed: Buy chart legend colours now match the chart slice colours
* Fixed: About page showed hardcoded version "v2.6" — now uses the CPT_VERSION constant
* Fixed: Dark mode — pie chart background colour is now consistent with other dashboard charts
* Fixed: All Transactions table sort — corrected data attribute names (data-sort to data-column)
* Fixed: P/L zone card borders overridden by CSS isolation block — restored via increased specificity
* Fixed: "Show P/L Zones" toggle showed a double dot caused by theme CSS — redesigned as a native button element

= 3.0.1 =
* Fixed: Shortcode public view (non-logged-in users) showed incorrect portfolio data — wrong quantities, wrong cost basis, $0 realized P/L
* Fixed: `cpt_calculate_grouped_portfolio()` now receives explicit `portfolio_id` so sales deductions apply correctly in public view
* Fixed: `CPT_Data_Access::get_sales()` now accepts `portfolio_id` parameter to avoid resolving against wrong user context
* Fixed: `get_all_transactions_with_ids()` now supports public view (portfolio owner lookup) — fixes realized P/L = $0 for guests
* Fixed: `get_current_portfolio_id()` public view fallback now scoped to site admin instead of any user's default portfolio

= 3.0.0 =
* Added: Freemius integration for premium license management (opt-in only)
* Added: Upsell notices for premium features (dismissible per user)
* Added: Admin About page
* Added: Social share widget for portfolio snapshots
* Added: Withdrawal transaction type
* Added: Admin shortcodes reference page
* Added: Import/export modal with JSON and CSV support
* Added: Dashboard collapsible sections
* Added: Toast notification system
* Added: Dark mode support
* Added: Responsive design improvements
* Added: ROI percentage chart
* Added: Advanced donut chart (Premium)
* Improved: Asset versioning — all scripts and styles now use the plugin version constant
* Improved: Admin dashboard layout and metrics
* Improved: Price cache reliability
* Fixed: Escaping on all dynamic output (wp.org compliance)
* Fixed: All Chart.js instances moved to local bundle (no CDN)

= 2.5 =
* Improved dashboard performance
* Added multi-portfolio support (now Premium feature)
* Enhanced import/export functionality
* Bug fixes and stability improvements

= 2.0 =
* Added snapshot and forecasting features
* Improved chart visualizations
* Stablecoin tracking support

= 1.0 =
* Initial release

== Upgrade Notice ==

= 4.0.0 =
BREAKING: Multi-portfolio, Reports, and premium features moved to Sakurato CPT Pro (https://sakurato.tech/). Install the add-on before updating if you use multiple portfolios. All data is preserved in the database.

= 3.5.0 =
BREAKING: All shortcodes renamed with `sakurato_` prefix (e.g. `[crypto_portfolio]` → `[sakurato_crypto_portfolio]`). Update any pages using old shortcodes after upgrade. All previously paid features are now free.

= 3.2.0 =
Reports sections are now a Premium feature — free users get a preview of up to 3 rows per section. Upgrade to unlock full access to Buy, Sell, Withdrawal, and Tax Summary data.

= 3.0.0 =
Major update: improved performance, full WordPress.org compliance, and new premium features via optional upgrade. Recommended for all users.

== External Services ==

This plugin connects to the following external services:

**CoinGecko API**
This plugin retrieves cryptocurrency price data and coin metadata from the CoinGecko public API. Requests are made server-side (via `wp_remote_get`) and contain only coin identifiers (e.g. `bitcoin`, `ethereum`) — no personal data or user information is transmitted.

* API endpoint: https://api.coingecko.com/api/v3 (free / demo tier)
* Pro endpoint (optional): https://pro-api.coingecko.com/api/v3
* CoinGecko Terms of Service: https://coingecko.com/terms
* CoinGecko Privacy Policy: https://coingecko.com/privacy
