Bicrypto 6.5.5

17 July 2026

WALLETSPNLBALANCESMYSQLMARIADBJSONMODELSEXCHANGEDEPOSITSWITHDRAWALSNFTECOSYSTEMDIAGNOSTICSADMIN-UIBUG-FIXES

Core v6.5.5

Release Date: July 17, 2026 Tags: WALLETS, PNL, BALANCES, MYSQL, MARIADB, JSON, MODELS, EXCHANGE, DEPOSITS, WITHDRAWALS, NFT, ECOSYSTEM, DIAGNOSTICS, ADMIN-UI, BUG-FIXES

Overview

Version 6.5.5 fixes two production-only failures — bugs that never reproduce in development, which is exactly how both shipped.

The first took the wallets page down entirely on MySQL-backed installs: every balance request returned a 500, so total balances, the 24h change and the PnL chart never loaded. The second stopped the Chain Requirements & Diagnostics page loading on every production install.

It also ends a long-standing confusion around ecosystem token balances, where three pages showed two different numbers for the same wallet.

Update Instructions

The usual pnpm updator is all that is required.


Fixed

Wallets page on MySQL: balances calculate again

What broke

On production installs backed by MySQL, the wallets page could not calculate balances at all: the wallet stats request failed with "[object Object]" is not valid JSON on every request, and the wallet list's PnL chart failed the same way. MariaDB-backed installs (including most dev environments) were unaffected, which is exactly why the bug survived testing.

Why it only happened on MySQL

MySQL has a native JSON column type, and the driver hands those values to the application already parsed — as objects. MariaDB stores JSON as LONGTEXT, so the same read delivers the raw string. Anything that unconditionally parses that value as text therefore works on one engine and throws on the other. The wallet PnL balances were the trigger — and because the daily PnL job guarantees a row always exists, the stats request hit it on literally every call.

What changed

Every JSON column in the platform's data layer is now read the same guarded way: parse only when a string actually arrives, pass already-parsed values through untouched, and fall back to the safe default (instead of failing the whole request) if a stored row is ever corrupt. The audit covered the complete data layer, not just the wallet path:

  • Finance: wallet PnL balances (the trigger), deposit method and withdraw method custom fields.
  • Exchange: the per-order fill list, read by order history on both engines.
  • NFT extension: activities, bids, collections, comments, disputes and dispute messages, listings, fractional shares, marketplaces, offers, royalties, sales and tokens.

Plain text columns (exchange, futures and ecosystem market metadata, forex instrument and session-calendar fields), which always arrive as strings on both engines, were checked and deliberately left unchanged.

Chain Requirements & Diagnostics page loads on production again

What broke

On every production install, opening the Chain Requirements & Diagnostics page failed because its API route could not load, reporting a missing blockchain-licence module. Development and demo environments were unaffected — again, exactly why it shipped.

Why it only happened on shipped builds

Production builds package the security layer (license validation, integrity checks) as a single protected bundle exposed through one entry point; the individual pieces that exist in the source tree are not present on disk in a shipped build. The blockchain requirements endpoint — alone in the entire codebase — reached past that entry point. In development the raw source exists and it resolves; on a shipped build it points at nothing, and the whole route fails at load time before a single request is handled.

What changed

The blockchain requirements endpoint now goes through the security entry point, matching every other consumer (the XMR, TRON, TON and SOL services all already did it this way). A full sweep confirmed the fix is complete in both directions: nothing else reaches past that entry point, and the security layer is the only part of the build where source and shipped output intentionally differ — so no other route can fail the same way.

Ecosystem tokens: one balance number everywhere

What users saw

For an ecosystem token, three pages could show two very different numbers: the wallets list showed the real balance, while the deposit page's "Current balance" and the wallet detail page's per-network "Network balance" could show a figure many times higher. Users reasonably read the bigger number as their balance — and then the wallets list looked like missing funds.

Why the numbers differed

Ecosystem wallets keep an internal per-network accounting figure alongside the real balance. It tracks funds moving on-chain — deposits raise it, withdrawals and cross-wallet transfers lower it — because the platform needs to know how much of a wallet's holdings each network can serve. What it does not track is trading: when a user sells tokens on the exchange, the real balance moves to the buyer instantly and off-chain, but nothing has moved on any network, so the per-network figure stays where it was. Deposit a large amount, sell most of it, and the deposit page still shows the original figure while the real balance is a fraction of it. Both pages were reading this internal number as if it were the user's balance.

What changed

The deposit page's "Current balance" now shows the wallet's actual balance — the same number as the wallets list, and the same number the deposit success screen reports after crediting. The wallet detail page no longer displays the internal per-network figure at all; the network section keeps the deposit address and QR code, and the page's Balance / Locked / Total metrics remain the single source of truth. The internal accounting value itself is untouched — withdrawals and transfers still use it — it just no longer masquerades as a user balance.