{"id":303679,"date":"2026-05-07T10:19:39","date_gmt":"2026-05-07T10:19:39","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/sakurato-crypto-portfolio-tracker\/"},"modified":"2026-05-14T04:29:52","modified_gmt":"2026-05-14T04:29:52","slug":"sakurato-crypto-portfolio-tracker","status":"publish","type":"plugin","link":"https:\/\/test.wordpress.org\/plugins\/sakurato-crypto-portfolio-tracker\/","author":23410481,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"4.1.0","stable_tag":"4.1.0","tested":"6.9.4","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"Sakurato Crypto Portfolio Tracker","header_author":"Sakurato.tech","header_description":"Track your cryptocurrency portfolio with real-time prices, profit\/loss calculations, performance charts, and full transaction history. Single-portfolio core; install the optional Sakurato CPT Pro add-on for unlimited multi-portfolio, full Reports module, and CSV export.","assets_banners_color":"3d3c49","last_updated":"2026-05-14 04:29:52","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/sakurato.tech\/crypto-portfolio-tracker\/","header_author_uri":"https:\/\/sakurato.tech","rating":0,"author_block_rating":0,"active_installs":0,"downloads":131,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"4.1.0":{"tag":"4.1.0","author":"sakurato","date":"2026-05-14 04:29:52"}},"upgrade_notice":{"4.0.0":"<p>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.<\/p>","3.5.0":"<p>BREAKING: All shortcodes renamed with <code>sakurato_<\/code> prefix (e.g. <code>[crypto_portfolio]<\/code> \u2192 <code>[sakurato_crypto_portfolio]<\/code>). Update any pages using old shortcodes after upgrade. All previously paid features are now free.<\/p>","3.2.0":"<p>Reports sections are now a Premium feature \u2014 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.<\/p>","3.0.0":"<p>Major update: improved performance, full WordPress.org compliance, and new premium features via optional upgrade. Recommended for all users.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.gif":{"filename":"icon-128x128.gif","revision":3525606,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-128x128.png":{"filename":"icon-128x128.png","revision":3525369,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.gif":{"filename":"icon-256x256.gif","revision":3525567,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3525369,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.jpg":{"filename":"banner-1544x500.jpg","revision":3528747,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3528747,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3531570,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"siteOptions\":{\"blogname\":\"Sakurato Demo\",\"blogdescription\":\"Crypto Portfolio Tracker - Live Demo\"},\"landingPage\":\"\\\/wp-admin\\\/admin.php?page=crypto-portfolio-dashboard\",\"steps\":[{\"step\":\"login\",\"username\":\"admin\",\"password\":\"password\"},{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"sakurato-crypto-portfolio-tracker\"},\"options\":{\"activate\":true}},{\"step\":\"request\",\"request\":{\"url\":\"\\\/wp-admin\\\/admin.php?page=crypto-portfolio-dashboard\",\"method\":\"GET\"}},{\"step\":\"runPHP\",\"code\":\"<?php\\nrequire('\\\/wordpress\\\/wp-load.php');\\nglobal $wpdb;\\n$user_id = 1;\\n\\n\\\/\\\/ 1. Use existing default portfolio created on activation\\n$portfolio_id = $wpdb->get_var(\\n    $wpdb->prepare(\\n        \\\"SELECT id FROM {$wpdb->prefix}cpt_portfolios WHERE user_id = %d AND is_default = 1 LIMIT 1\\\",\\n        $user_id\\n    )\\n);\\nif (!$portfolio_id) {\\n    $wpdb->insert(\\n        $wpdb->prefix . 'cpt_portfolios',\\n        ['user_id'=>$user_id,'name'=>'My Crypto Portfolio','description'=>'','color'=>'#3b82f6','is_default'=>1,'first_transaction_at'=>'2025-01-15 10:00:00','first_snapshot_created'=>1,'created_at'=>'2025-01-15 10:00:00'],\\n        ['%d','%s','%s','%s','%d','%s','%d','%s']\\n    );\\n    $portfolio_id = $wpdb->insert_id;\\n} else {\\n    $wpdb->update(\\n        $wpdb->prefix . 'cpt_portfolios',\\n        ['name'=>'My Crypto Portfolio','description'=>'Demo: BTC, ETH, SOL, BNB','first_transaction_at'=>'2025-01-15 10:00:00','first_snapshot_created'=>1],\\n        ['id'=>$portfolio_id],\\n        ['%s','%s','%s','%d'],\\n        ['%d']\\n    );\\n}\\n\\n\\\/\\\/ 2. Transactions\\n$txs = [\\n    ['buy','bitcoin','BTC',      0.5,    42000.0,  21000.00, '2025-01-15 10:00:00', 'new_funds',        null],\\n    ['buy','ethereum','ETH',     3.0,     2200.0,   6600.00, '2025-02-01 12:00:00', 'new_funds',        null],\\n    ['buy','solana','SOL',      50.0,      150.0,   7500.00, '2025-03-10 09:00:00', 'new_funds',        null],\\n    ['buy','binancecoin','BNB',  5.0,      380.0,   1900.00, '2025-04-05 15:00:00', 'new_funds',        null],\\n    ['sell','ethereum','ETH',    1.0,     3500.0,   3500.00, '2025-08-20 14:00:00', 'sale_proceeds',    null],\\n    ['buy','bitcoin','BTC',      0.1,    55000.0,   5500.00, '2025-11-10 11:00:00', 'new_funds',        null],\\n];\\nforeach ($txs as $t) {\\n    $wpdb->insert(\\n        $wpdb->prefix . 'cpt_transactions',\\n        [\\n            'user_id'          => $user_id,\\n            'portfolio_id'     => $portfolio_id,\\n            'transaction_type' => $t[0],\\n            'coin_id'          => $t[1],\\n            'coin_symbol'      => $t[2],\\n            'quantity'         => $t[3],\\n            'price_per_unit'   => $t[4],\\n            'total_cost'       => $t[5],\\n            'transaction_date' => $t[6],\\n            'payment_source'   => $t[7],\\n            'notes'            => $t[8],\\n            'is_final'         => 0\\n        ],\\n        ['%d','%d','%s','%s','%s','%f','%f','%f','%s','%s','%s','%d']\\n    );\\n}\\n\\n\\\/\\\/ 3. Historical snapshots for ROI chart\\n$snapshots = [\\n    ['2025-01-31', 21000.00, 22500.00,  1500.00,  7.14,  0, 0],\\n    ['2025-02-28', 27600.00, 30200.00,  2600.00,  9.42,  0, 0],\\n    ['2025-03-31', 35100.00, 39800.00,  4700.00, 13.39,  0, 0],\\n    ['2025-04-30', 37000.00, 44500.00,  7500.00, 20.27,  0, 0],\\n    ['2025-05-31', 37000.00, 41200.00,  4200.00, 11.35,  0, 0],\\n    ['2025-06-30', 37000.00, 43700.00,  6700.00, 18.11,  0, 0],\\n    ['2025-07-31', 37000.00, 48900.00, 11900.00, 32.16,  0, 0],\\n    ['2025-08-31', 37000.00, 53200.00, 16200.00, 43.78,  0, 0],\\n    ['2025-09-30', 37000.00, 49600.00, 12600.00, 34.05,  0, 0],\\n    ['2025-10-31', 37000.00, 55100.00, 18100.00, 48.92,  0, 0],\\n    ['2025-11-30', 42500.00, 72400.00, 29900.00, 70.35,  0, 0],\\n    ['2025-12-31', 42500.00, 68200.00, 25700.00, 60.47,  0, 0],\\n    ['2026-01-31', 42500.00, 61500.00, 19000.00, 44.71,  0, 0],\\n    ['2026-02-28', 42500.00, 57300.00, 14800.00, 34.82,  0, 0],\\n    ['2026-03-31', 42500.00, 53800.00, 11300.00, 26.59,  0, 0],\\n    ['2026-04-30', 42500.00, 51800.00,  9300.00, 21.88,  0, 0],\\n    ['2026-05-04', 42500.00, 53400.00, 10900.00, 25.65,  0, 0],\\n];\\nforeach ($snapshots as $s) {\\n    $wpdb->insert(\\n        $wpdb->prefix . 'cpt_snapshots',\\n        [\\n            'portfolio_id'          => $portfolio_id,\\n            'user_id'               => $user_id,\\n            'snapshot_date'         => $s[0] . ' 23:59:59',\\n            'total_invested'        => $s[1],\\n            'total_value'           => $s[2],\\n            'profit_loss'           => $s[3],\\n            'profit_loss_percent'   => $s[4],\\n            'total_withdrawn_cost'  => $s[5],\\n            'total_withdrawn_value' => $s[6]\\n        ],\\n        ['%d','%d','%s','%f','%f','%f','%f','%f','%f']\\n    );\\n}\\n\\n$wpdb->update(\\n    $wpdb->prefix . 'cpt_portfolios',\\n    ['first_snapshot_created' => 1],\\n    ['id' => $portfolio_id],\\n    ['%d'],\\n    ['%d']\\n);\\n\\necho 'Demo data imported OK \\u2013 portfolio_id=' . $portfolio_id;\\n\"}]}"}},"all_blocks":[],"tagged_versions":["4.1.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3525369,"resolution":"1","location":"assets","locale":"","width":1200,"height":799},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3525369,"resolution":"2","location":"assets","locale":"","width":1200,"height":799},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3525369,"resolution":"3","location":"assets","locale":"","width":1200,"height":799},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3525369,"resolution":"4","location":"assets","locale":"","width":1200,"height":799},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3525369,"resolution":"5","location":"assets","locale":"","width":1200,"height":799}},"screenshots":{"1":"Admin dashboard \u2014 portfolio value, Total\/Unrealized\/Realized P\/L cards, ROI Performance chart, and Holdings Distribution donut chart.","2":"Portfolio holdings table \u2014 coin list with quantities, average buy price, current price, cost basis, current value, and P\/L per position.","3":"Frontend shortcodes \u2014 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 \u2014 CoinGecko API key configuration, rate-limit tier selection, cache status, and troubleshooting panel.","5":"Import &amp; Export \u2014 backup portfolio data to JSON or CSV, and restore or migrate portfolios from a file."},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[1886,21057,12611,789,5352],"plugin_category":[43,45],"plugin_contributors":[262156],"plugin_business_model":[],"class_list":["post-303679","plugin","type-plugin","status-publish","hentry","plugin_tags-bitcoin","plugin_tags-crypto","plugin_tags-cryptocurrency","plugin_tags-portfolio","plugin_tags-tracker","plugin_category-customization","plugin_category-ecommerce","plugin_contributors-sakurato","plugin_committers-sakurato"],"banners":{"banner":"https:\/\/ps.w.org\/sakurato-crypto-portfolio-tracker\/assets\/banner-772x250.jpg?rev=3528747","banner_2x":"https:\/\/ps.w.org\/sakurato-crypto-portfolio-tracker\/assets\/banner-1544x500.jpg?rev=3528747","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/sakurato-crypto-portfolio-tracker\/assets\/icon-128x128.png?rev=3525369","icon_2x":"https:\/\/ps.w.org\/sakurato-crypto-portfolio-tracker\/assets\/icon-256x256.png?rev=3525369","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/sakurato-crypto-portfolio-tracker\/assets\/screenshot-1.png?rev=3525369","caption":"Admin dashboard \u2014 portfolio value, Total\/Unrealized\/Realized P\/L cards, ROI Performance chart, and Holdings Distribution donut chart."},{"src":"https:\/\/ps.w.org\/sakurato-crypto-portfolio-tracker\/assets\/screenshot-2.png?rev=3525369","caption":"Portfolio holdings table \u2014 coin list with quantities, average buy price, current price, cost basis, current value, and P\/L per position."},{"src":"https:\/\/ps.w.org\/sakurato-crypto-portfolio-tracker\/assets\/screenshot-3.png?rev=3525369","caption":"Frontend shortcodes \u2014 Portfolio Value chart (Current Value vs Invested capital with P\/L Zones toggle) and Portfolio ROI Performance chart embedded on any page."},{"src":"https:\/\/ps.w.org\/sakurato-crypto-portfolio-tracker\/assets\/screenshot-4.png?rev=3525369","caption":"API Settings \u2014 CoinGecko API key configuration, rate-limit tier selection, cache status, and troubleshooting panel."},{"src":"https:\/\/ps.w.org\/sakurato-crypto-portfolio-tracker\/assets\/screenshot-5.png?rev=3525369","caption":"Import &amp; Export \u2014 backup portfolio data to JSON or CSV, and restore or migrate portfolios from a file."}],"raw_content":"<!--section=description-->\n<p>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, and display selected portfolio data on the frontend with shortcodes.<\/p>\n\n<p><strong>The plugin does not connect to your wallet or exchange accounts.<\/strong> You manually add your transactions \u2014 the plugin then fetches public market prices from the CoinGecko API to calculate current portfolio value. No personal data is sent to external services.<\/p>\n\n<p>Real-time prices are powered by the CoinGecko public API \u2014 no API key required, and over 13,000 coins and tokens are supported.<\/p>\n\n\n\n<p><strong>\u25b6 <a href=\"https:\/\/wordpress.org\/plugins\/sakurato-crypto-portfolio-tracker\/?preview=1\">Try the Live Preview<\/a> \u2014 see the plugin in action before you install. No account required.<\/strong><\/p>\n\n\n\n<p><strong>Features:<\/strong><\/p>\n\n<ul>\n<li>Single portfolio with full transaction history (buy \/ sell \/ withdraw)<\/li>\n<li>Real-time price updates via CoinGecko API (no API key required)<\/li>\n<li>Portfolio value and ROI calculations<\/li>\n<li>Performance charts (Chart.js \u2014 served locally, no CDN)<\/li>\n<li>Performance Periods dashboard (24H, 7D, 30D, 60D, 180D, 1Y, ALL) with sparklines<\/li>\n<li>Stablecoin tracking (USDT, USDC, DAI, and more)<\/li>\n<li>Admin dashboard with metrics overview<\/li>\n<li>Import \/ export portfolio data \u2014 JSON (full) and CSV (import and export)<\/li>\n<li>Portfolio snapshots<\/li>\n<li>Portfolio notes<\/li>\n<li>Shortcodes for frontend display (use the <code>sakurato_<\/code> prefix, e.g. <code>[sakurato_crypto_portfolio]<\/code>)<\/li>\n<li>Pie and ROI charts<\/li>\n<li>Holdings Distribution donut on dashboard (top 7 holdings + \"Other\")<\/li>\n<li>Social share widget for portfolio snapshots<\/li>\n<li>Dark mode support<\/li>\n<li>Responsive design<\/li>\n<\/ul>\n\n<p><strong>Pro Add-on (optional)<\/strong><\/p>\n\n<p>An optional <strong><a href=\"https:\/\/sakurato.tech\/\">Sakurato CPT Pro<\/a><\/strong> add-on extends this free plugin with: unlimited multi-portfolio management, 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.<\/p>\n\n<h3>External Services<\/h3>\n\n<p>This plugin connects to the following external services:<\/p>\n\n<p><strong>CoinGecko API<\/strong>\nThis plugin retrieves cryptocurrency price data and coin metadata from the CoinGecko public API. Requests are made server-side (via <code>wp_remote_get<\/code>) and contain only coin identifiers (e.g. <code>bitcoin<\/code>, <code>ethereum<\/code>) \u2014 no personal data or user information is transmitted.<\/p>\n\n<ul>\n<li>API endpoint: https:\/\/api.coingecko.com\/api\/v3 (free \/ demo tier)<\/li>\n<li>Pro endpoint (optional): https:\/\/pro-api.coingecko.com\/api\/v3<\/li>\n<li>CoinGecko Terms of Service: https:\/\/coingecko.com\/terms<\/li>\n<li>CoinGecko Privacy Policy: https:\/\/coingecko.com\/privacy<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>crypto-portfolio-tracker<\/code> folder to the <code>\/wp-content\/plugins\/<\/code> directory.<\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> menu in WordPress.<\/li>\n<li>Navigate to <strong>Crypto Portfolio<\/strong> in the admin menu to get started.<\/li>\n<li>Add your first cryptocurrency transaction and configure your portfolio settings.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20plugin%20require%20an%20api%20key%3F\"><h3>Does this plugin require an API key?<\/h3><\/dt>\n<dd><p>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.<\/p><\/dd>\n<dt id=\"how%20many%20portfolios%20can%20i%20track%3F\"><h3>How many portfolios can I track?<\/h3><\/dt>\n<dd><p>The free plugin supports a single portfolio per user. For unlimited portfolios install the optional Sakurato CPT Pro add-on (https:\/\/sakurato.tech\/).<\/p><\/dd>\n<dt id=\"what%20cryptocurrencies%20are%20supported%3F\"><h3>What cryptocurrencies are supported?<\/h3><\/dt>\n<dd><p>All cryptocurrencies listed on CoinGecko are supported \u2014 that is over 13,000 coins and tokens.<\/p><\/dd>\n<dt id=\"can%20i%20import%20existing%20portfolio%20data%3F\"><h3>Can I import existing portfolio data?<\/h3><\/dt>\n<dd><p>Yes. The plugin supports importing portfolio data from JSON and CSV files.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20use%20any%20external%20javascript%20libraries%20from%20a%20cdn%3F\"><h3>Does the plugin use any external JavaScript libraries from a CDN?<\/h3><\/dt>\n<dd><p>No. Chart.js is bundled with the plugin and served locally. No external CDN calls are made.<\/p><\/dd>\n<dt id=\"what%20data%20does%20the%20plugin%20send%20to%20external%20services%3F\"><h3>What data does the plugin send to external services?<\/h3><\/dt>\n<dd><p>Only coin identifiers (e.g. <code>bitcoin<\/code>, <code>ethereum<\/code>) 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.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20connect%20to%20my%20crypto%20wallet%20or%20exchange%20account%3F\"><h3>Does the plugin connect to my crypto wallet or exchange account?<\/h3><\/dt>\n<dd><p>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.<\/p><\/dd>\n<dt id=\"is%20my%20portfolio%20data%20sent%20to%20any%20external%20server%3F\"><h3>Is my portfolio data sent to any external server?<\/h3><\/dt>\n<dd><p>No. Your portfolio transactions are stored in your WordPress database only. The plugin sends only coin identifiers (e.g. <code>bitcoin<\/code>) to the CoinGecko API to fetch public price data. No portfolio data, wallet addresses, or personal information is transmitted.<\/p><\/dd>\n<dt id=\"will%20this%20plugin%20slow%20down%20my%20website%3F\"><h3>Will this plugin slow down my website?<\/h3><\/dt>\n<dd><p>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 \u2014 frontend visitors never wait for external API calls.<\/p><\/dd>\n<dt id=\"can%20i%20display%20my%20portfolio%20on%20the%20frontend%3F\"><h3>Can I display my portfolio on the frontend?<\/h3><\/dt>\n<dd><p>Yes. Use the provided shortcodes (e.g. <code>[sakurato_crypto_portfolio]<\/code>) to embed portfolio data on any page or post.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>4.1.0<\/h4>\n\n<ul>\n<li>Fixed: Cron stampede \u2014 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<\/li>\n<li>Fixed: PHP 8.1 deprecation warning (<code>strpos(null)<\/code>) \u2014 <code>cached_at<\/code> timestamp now stamped correctly on both sync and async price fetch paths<\/li>\n<li>Fixed: P\/L Zones chart \u2014 red gradient now renders correctly for portfolios in loss (gradient was reversed, making the fill invisible)<\/li>\n<li>Added: \"Create New Portfolio\" import mode is now gated \u2014 free plugin shows Merge\/Replace only; Sakurato CPT Pro unlocks the Create New option<\/li>\n<li>Fixed: Mobile responsive tables \u2014 All Transactions, Sales History, and Snapshots tables now scroll horizontally on \u2264782px instead of collapsing to WP card layout<\/li>\n<li>Removed: <code>admin-reports.css<\/code> from free build (reports CSS belongs to Sakurato CPT Pro add-on)<\/li>\n<\/ul>\n\n<h4>4.0.0<\/h4>\n\n<ul>\n<li><strong>BREAKING ARCHITECTURE CHANGE<\/strong>: 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<\/li>\n<li>Removed: Freemius SDK and the entire <code>freemius\/<\/code> directory (~3.5 MB) \u2014 no third-party licensing code in the WP.org build<\/li>\n<li>Removed: Reports module (Buy \/ Sell \/ Withdrawal \/ Tax Summary, summary CSV export) \u2014 moved to the Sakurato CPT Pro add-on<\/li>\n<li>Removed: Multi-portfolio management page (Portfolio Manager submenu) \u2014 moved to the Sakurato CPT Pro add-on<\/li>\n<li>Removed: All upsell notices and dynamic upgrade URLs \u2014 replaced with a single static link to https:\/\/sakurato.tech\/ on the About page<\/li>\n<li>Added: Native <code>uninstall.php<\/code> \u2014 clean removal of options, transients, cron events and database tables when the plugin is deleted<\/li>\n<li>Added: Extension hook <code>do_action( 'sakurato_cpt_admin_menu_after' )<\/code> \u2014 pro add-on registers Reports and Portfolio Manager submenus here<\/li>\n<li>Added: Extension hook <code>do_action( 'sakurato_cpt_dashboard_after_charts' )<\/code> \u2014 pro renders the Premium Donut Chart here<\/li>\n<li>Added: Extension hook <code>do_action( 'sakurato_cpt_export_handlers_init', $handler )<\/code> \u2014 pro registers CSV exporter and multi-portfolio exporter<\/li>\n<li>Added: Extension filter <code>apply_filters( 'sakurato_cpt_portfolio_limit', 1 )<\/code> \u2014 defaults to 1 in free, pro returns <code>PHP_INT_MAX<\/code><\/li>\n<li>Added: <code>wp_add_privacy_policy_content()<\/code> \u2014 describes local-only data storage and CoinGecko coin-ID-only API requests<\/li>\n<\/ul>\n\n<h4>3.5.0<\/h4>\n\n<ul>\n<li><strong>BREAKING<\/strong>: All shortcode tags renamed with <code>sakurato_<\/code> prefix (e.g. <code>[crypto_portfolio]<\/code> \u2192 <code>[sakurato_crypto_portfolio]<\/code>, <code>[crypto_portfolio_chart]<\/code> \u2192 <code>[sakurato_crypto_portfolio_chart]<\/code>, etc.). Update existing pages \u2014 see Upgrade Notice below<\/li>\n<li>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<\/li>\n<li>Fixed: CoinGecko Terms\/Privacy URLs in readme corrected (removed <code>\/en\/<\/code> segment that failed SSL validation on WP.org)<\/li>\n<li>Fixed: Freemius SDK loading guarded with <code>function_exists( 'fs_dynamic_init' )<\/code> to prevent conflicts with other plugins bundling Freemius<\/li>\n<li>Security: Added <code>current_user_can( 'manage_options' )<\/code> capability checks to transaction delete and edit handlers<\/li>\n<li>Changed: All <code>wp_localize_script()<\/code> global JS variables now use the <code>sakuratoCpt*<\/code> prefix (<code>cptFrontend<\/code> \u2192 <code>sakuratoCptFrontend<\/code>, <code>cptDashboard<\/code> \u2192 <code>sakuratoCptDashboard<\/code>, <code>cptData<\/code> \u2192 <code>sakuratoCptData<\/code>, <code>cptExportImport<\/code> \u2192 <code>sakuratoCptExportImport<\/code>, <code>cptSocialData<\/code> \u2192 <code>sakuratoCptSocialData<\/code>)<\/li>\n<li>Changed: Admin page slugs renamed (<code>cpt-reports<\/code> \u2192 <code>sakurato-cpt-reports<\/code>, <code>cpt-about<\/code> \u2192 <code>sakurato-cpt-about<\/code>)<\/li>\n<li>Changed: Chart format settings sanitizer now whitelists allowed fields and clamps numeric values to safe ranges<\/li>\n<li>Removed: Premium upsell banner from the Reports page (full Reports summary visible to everyone)<\/li>\n<\/ul>\n\n<h4>3.4.0<\/h4>\n\n<ul>\n<li>Added: Dashboard Performance Periods section with 7 time ranges (24H, 7D, 30D, 60D, 180D, 1Y, ALL) and sparklines<\/li>\n<li>Added: New <code>[crypto_portfolio_performance]<\/code> shortcode for embedded performance cards<\/li>\n<li>Added: <code>show_values<\/code> parameter for pie chart and performance chart shortcodes<\/li>\n<li>Fixed: Shortcode output now properly escaped with <code>esc_html()<\/code> (WP.org compliance)<\/li>\n<li>Fixed: <code>register_setting()<\/code> sanitizer updated with per-field validators (<code>sanitize_hex_color<\/code>, <code>absint<\/code>)<\/li>\n<li>Fixed: Nonce verification added to portfolio settings GET action<\/li>\n<li>Changed: Reports tab removed from free version (available in Premium add-on)<\/li>\n<li>Changed: Portfolio creation UI removed from free version (single-portfolio by design)<\/li>\n<li>Removed: All Freemius <code>is_paying()<\/code> feature-restriction checks from WP.org build<\/li>\n<\/ul>\n\n<h4>3.3.1<\/h4>\n\n<ul>\n<li>Fixed: Freemius SDK set to <code>is_premium=false<\/code>, <code>is_org_compliant=true<\/code> for WordPress.org compliance<\/li>\n<li>Fixed: Replaced inline <code>&lt;style&gt;<\/code> injections in chart shortcodes with static CSS file + CSS custom properties on wrapper elements<\/li>\n<li>Fixed: Export CSV button and Reports section now correctly gated behind Premium license<\/li>\n<\/ul>\n\n<h4>3.3.0<\/h4>\n\n<ul>\n<li>Performance: Price cache moved from wp_options (autoload=yes, 150-300 KB loaded on every WP request) to a dedicated database table <code>wp_cpt_price_cache<\/code><\/li>\n<li>Performance: Stale-while-revalidate \u2014 frontend requests always return immediately from DB; background cron job refreshes stale coins asynchronously<\/li>\n<li>Performance: sleep() calls (rate-limit protection, 429 backoff) moved out of request path; they now execute only in background\/cron context<\/li>\n<li>Improved: Atomic <code>INSERT ... ON DUPLICATE KEY UPDATE<\/code> upserts eliminate race conditions when multiple cron jobs run in parallel<\/li>\n<li>Improved: Filterable TTL values \u2014 override via <code>sakurato_cpt_price_cache_soft_ttl<\/code> (default 5 min), <code>_hard_ttl<\/code> (30 min), <code>_top_coins_list_ttl<\/code> (24 h) filters<\/li>\n<li>Fixed: Top coins list (<code>sakurato_cpt_top_500_coins_list<\/code>) now saved with <code>autoload=no<\/code><\/li>\n<li>Compatibility: Existing installations automatically migrate old cache data on first update (idempotent migration)<\/li>\n<\/ul>\n\n<h4>3.2.0<\/h4>\n\n<ul>\n<li>Added: Reports sections (Buy, Sell, Withdrawal, Tax Summary) are now a Premium feature \u2014 free users see a preview of up to 3 rows per section with a blur\/lock overlay and upgrade prompt<\/li>\n<li>Updated: Upsell admin notice updated to highlight Reports access as a premium benefit alongside multiple portfolios<\/li>\n<li>Fixed: Withdrawal modal coin list failed to load due to an incorrect AJAX action name<\/li>\n<li>Fixed: Plugin Check compliance \u2014 SQL interpolation annotations, missing translators comments, direct DB query suppression<\/li>\n<\/ul>\n\n<h4>3.1.1<\/h4>\n\n<ul>\n<li>Fix: Moved all inline style\/script blocks to wp_add_inline_style() and wp_add_inline_script() for WP.org compliance<\/li>\n<li>Fix: Added wp_strip_all_tags() escaping for dynamic CSS output in shortcode chart styles<\/li>\n<li>Fix: Enqueued admin-inline.css for P\/L cards, price cache indicator, and time filter styles<\/li>\n<\/ul>\n\n<h4>3.1.0<\/h4>\n\n<ul>\n<li>Added: Reports tab \u2014 Buy Transactions, Sell Transactions, Withdrawals, and Tax Summary sections with year\/month\/portfolio filters<\/li>\n<li>Added: Per-section Chart.js charts (funding-source donut for buys, monthly bar for sells, destination donut for withdrawals)<\/li>\n<li>Added: Column sorting and pagination (10 rows\/page) on all Reports tables<\/li>\n<li>Added: CSV export per section in Reports<\/li>\n<li>Added: 6 summary metric cards \u2014 Total Invested, Total Sold, Withdrawals, Net Capital Flow, Avg Buy Price, Avg Sell Price<\/li>\n<li>Added: Informational description in each Reports section explaining what data is shown<\/li>\n<li>Added: Download PNG button in Social Share widget (canvas-based, no server dependency)<\/li>\n<li>Added: Snapshots Management page now includes portfolio selector and info bar<\/li>\n<li>Added: Shortcode Generator expanded with 19 new parameters and dynamic show\/hide per shortcode type<\/li>\n<li>Improved: CSS isolation for all shortcodes \u2014 styles no longer affected by the active WordPress theme<\/li>\n<li>Improved: Pie chart vertical layout \u2014 tighter padding, legend fills full width, full coin name hidden<\/li>\n<li>Improved: Admin menu order: Dashboard \u2192 Transactions \u2192 Snapshots \u2192 Portfolios \u2192 Shortcodes \u2192 Import\/Export \u2192 API \u2192 About<\/li>\n<li>Improved: Reports mobile layout \u2014 tables scroll horizontally; less critical columns hidden on small screens<\/li>\n<li>Fixed: Sales History excluded internal portfolio swaps (USDT \u2192 Internal) \u2014 only real asset sales shown<\/li>\n<li>Fixed: Buy History excluded companion stablecoin entries from sales (Sale_proceeds payment source)<\/li>\n<li>Fixed: Monthly Sell chart totals excluded internal swaps<\/li>\n<li>Fixed: Tax Summary now groups by coin ID \u2014 same asset with different symbols (BTC \/ BITCOIN) appears as one row<\/li>\n<li>Fixed: Tax Summary Withdrawals column was always $0 \u2014 now correctly sums withdrawal values<\/li>\n<li>Fixed: Total Transactions metric and section badge counts show actual transaction count, not grouped row count<\/li>\n<li>Fixed: Buy chart legend colours now match the chart slice colours<\/li>\n<li>Fixed: About page showed hardcoded version \"v2.6\" \u2014 now uses the CPT_VERSION constant<\/li>\n<li>Fixed: Dark mode \u2014 pie chart background colour is now consistent with other dashboard charts<\/li>\n<li>Fixed: All Transactions table sort \u2014 corrected data attribute names (data-sort to data-column)<\/li>\n<li>Fixed: P\/L zone card borders overridden by CSS isolation block \u2014 restored via increased specificity<\/li>\n<li>Fixed: \"Show P\/L Zones\" toggle showed a double dot caused by theme CSS \u2014 redesigned as a native button element<\/li>\n<\/ul>\n\n<h4>3.0.1<\/h4>\n\n<ul>\n<li>Fixed: Shortcode public view (non-logged-in users) showed incorrect portfolio data \u2014 wrong quantities, wrong cost basis, $0 realized P\/L<\/li>\n<li>Fixed: <code>cpt_calculate_grouped_portfolio()<\/code> now receives explicit <code>portfolio_id<\/code> so sales deductions apply correctly in public view<\/li>\n<li>Fixed: <code>CPT_Data_Access::get_sales()<\/code> now accepts <code>portfolio_id<\/code> parameter to avoid resolving against wrong user context<\/li>\n<li>Fixed: <code>get_all_transactions_with_ids()<\/code> now supports public view (portfolio owner lookup) \u2014 fixes realized P\/L = $0 for guests<\/li>\n<li>Fixed: <code>get_current_portfolio_id()<\/code> public view fallback now scoped to site admin instead of any user's default portfolio<\/li>\n<\/ul>\n\n<h4>3.0.0<\/h4>\n\n<ul>\n<li>Added: Freemius integration for premium license management (opt-in only)<\/li>\n<li>Added: Upsell notices for premium features (dismissible per user)<\/li>\n<li>Added: Admin About page<\/li>\n<li>Added: Social share widget for portfolio snapshots<\/li>\n<li>Added: Withdrawal transaction type<\/li>\n<li>Added: Admin shortcodes reference page<\/li>\n<li>Added: Import\/export modal with JSON and CSV support<\/li>\n<li>Added: Dashboard collapsible sections<\/li>\n<li>Added: Toast notification system<\/li>\n<li>Added: Dark mode support<\/li>\n<li>Added: Responsive design improvements<\/li>\n<li>Added: ROI percentage chart<\/li>\n<li>Added: Advanced donut chart (Premium)<\/li>\n<li>Improved: Asset versioning \u2014 all scripts and styles now use the plugin version constant<\/li>\n<li>Improved: Admin dashboard layout and metrics<\/li>\n<li>Improved: Price cache reliability<\/li>\n<li>Fixed: Escaping on all dynamic output (wp.org compliance)<\/li>\n<li>Fixed: All Chart.js instances moved to local bundle (no CDN)<\/li>\n<\/ul>\n\n<h4>2.5<\/h4>\n\n<ul>\n<li>Improved dashboard performance<\/li>\n<li>Added multi-portfolio support (now Premium feature)<\/li>\n<li>Enhanced import\/export functionality<\/li>\n<li>Bug fixes and stability improvements<\/li>\n<\/ul>\n\n<h4>2.0<\/h4>\n\n<ul>\n<li>Added snapshot and forecasting features<\/li>\n<li>Improved chart visualizations<\/li>\n<li>Stablecoin tracking support<\/li>\n<\/ul>\n\n<h4>1.0<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<\/ul>","raw_excerpt":"Track your crypto portfolio in WordPress \u2014 real-time prices, P&amp;L, ROI charts, and transaction history. No wallet connection required.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/303679","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=303679"}],"author":[{"embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/sakurato"}],"wp:attachment":[{"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=303679"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=303679"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=303679"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=303679"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=303679"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/test.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=303679"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}