Bicrypto 6.6.9

Latest

19 August 2026

This release has upgrade notes. Read them before updating — they describe behaviour changes that need your attention.

TRADINGTERMINALWEBSOCKETSPERFORMANCEWALLETSDIAGNOSTICSBUG-FIXES

Core v6.6.9

Release Date: August 19, 2026 Tags: TRADING, TERMINAL, WEBSOCKETS, PERFORMANCE, WALLETS, DIAGNOSTICS, BUG-FIXES

Overview

A trading-terminal release, and the whole of it is about what a customer sees while a market is busy. On the Pro terminal, every order the exchange touched emptied the orders table to three placeholder rows and refilled it, and blanked the AVAILABLE balance figures at the same time. With a market-making bot working a ladder that happens dozens of times a second, so the table strobed continuously while the tab badge above it kept reporting the true open count.

The cause was that the terminal already had the changed order — the websocket sent it — and threw it away, then asked the server for everything again. It now uses what it was sent.

Two of the repairs are wrong numbers rather than flicker. Signing out and back in on the same pair could paint the previous account's balance, and on the standard trade page a pair switch left the Open Orders tab listing the market you had just left. Both are corrected here.

The backend also gains a slow-request line that names where a slow request spent its time — the instrument this release's own investigation was built on.

Update Instructions

pnpm updator

Restart the backend, and ship the frontend build — the terminal fixes are all client-side. No database change and nothing to run.

Anyone with a trading terminal already open should reload the tab once; a browser that has been open since before the update keeps the old code.


Upgrade Notes

Your backend log will start printing SLOW lines

From this release any request that takes longer than three seconds prints one extra warning naming the request and the four costliest steps inside it, including the time spent before the handler starts — the gates, the auth chain and the body parse — which was never visible before.

This is a diagnostic, not an alarm, and on a healthy install it still fires: anything that waits on somebody else's server — a payment provider, a blockchain node, an AI answer — is legitimately slower than three seconds and will now say so on every call. Read the line as "here is where the time went", not "here is a fault".

  • Set SLOW_REQUEST_MS in the backend environment to a different threshold in milliseconds, or SLOW_REQUEST_MS=0 to switch the report off entirely.
  • Restart the backend for a change to that value to take effect.

Added

A slow request now says where its time went

A request's console block has always listed its steps and closed with a single total. The two together are exactly what a latency report cannot use: an operator looking at a fourteen-second order placement over a dozen steps had no way to tell whether the wallet hold, the book read or the matching hand-off ate it, and what reached support was a screenshot of a spinner.

  • Added a SLOW warning line for any request over the threshold, naming the method, the path and the four costliest steps with their individual milliseconds. The gap before the first step is reported under its own name rather than folded into the handler.

Changed

The terminal reconciles itself at a bounded rate

Three separate parts of the trading pages answered every order and wallet event with an immediate request. Those events arrive one per order the exchange touches, so a bot re-quoting a ladder turned a single open terminal tab into a stream of requests that never stopped while the bot ran.

All three now share one rule: the first event in a quiet period still runs immediately — a customer cancelling an order sees it at once — everything inside the next two seconds is absorbed, and one final run is guaranteed after the burst. The last event of a burst is the one whose state matters, and a plain cooldown is precisely the mechanism that drops it.

  • Changed the Pro orders panel, the Pro balance figures and the standard trade page's order form to refresh at most once every two seconds under a stream, with a guaranteed final refresh.
  • Changed overlapping order-list reads to carry a generation marker, so only the newest response is committed. Two snapshots in flight across a cancel can no longer settle in the wrong order.
  • Changed a balance response to be discarded when the account, wallet type or pair it was requested for is no longer the one on screen.
  • Changed cached order rows to record the market they were fetched for, so a cache written for one pair is not rendered under another.
  • Changed the terminal to ignore order frames that arrive after the session has ended.

Fixed

The Pro orders table emptied and refilled while a bot worked

The websocket callback that learns an order has changed received the order itself and dropped it, dispatching a bare event whose only listener answered by re-requesting both order lists over HTTP. That request raises the panel's loading state, and the loading state does not mean "busy" to the Open Orders, Order History and Trade History tabs — it means replace every row with three placeholder rows. So each single order update deleted the whole table for the length of one round trip, while the tab badge, computed from state the refetch never cleared, went on displaying the real count above an empty list.

  • Fixed the Pro terminal's order table blanking on every order update. The changed order is now merged into the rows already on screen: a fill, a cancel or a newly placed order updates in place, with no request and no placeholder.
  • Fixed rows that did not change being rebuilt anyway, which repainted the whole table even once the blanking was gone.
  • Fixed a modify or a Cancel All on the Pro terminal issuing four extra order-list requests of its own, on top of the ones the resulting order frames already caused.

AVAILABLE balances strobed between the figure and a grey bar

The balance hooks raised their loading state on every read, including a refresh — and the loading state replaces the number with a pulsing placeholder. On the Pro terminal that read fires once per order the exchange touches, so both sides of the pair flickered for as long as a bot was quoting.

A refresh now keeps the number on screen and swaps it when the response lands. The placeholder remains for the two cases where the figure being held is not the right thing to show: a genuine first load, and a change of pair or account.

  • Fixed the Pro terminal's AVAILABLE figures blanking on every order event.
  • Fixed the same blanking on the standard trade page's order form, where it fired on the customer's own placement or cancellation — one blanked balance per action they took.

The previous account's balance could be shown to the next one

The balance cache lives for the lifetime of the page, not the session, and its key named only the wallet type and the pair. Signing out and back in on the same pair therefore found a populated cache under a matching key, and the figures the previous account had been looking at were rendered under the new account's name until a response arrived to replace them.

  • Fixed the account being left out of the balance cache key.
  • Fixed the order and balance caches surviving a sign-out. Both are cleared when the session ends.

A pair switch left the previous market's orders on screen

The standard trade page's order socket is deliberately registered once and not re-registered on a pair change — tearing the subscription down and rebuilding it loses frames that arrive in the gap. But the callback it held was the one built before the switch, closing over the pair you had left, so every subsequent frame fetched and rendered the wrong market's history. The list itself was never re-scoped either, so the Open Orders tab kept showing the previous market's resting orders under the new market's header.

  • Fixed the order-frame handler being frozen at the pair it was registered with. The subscription stays put and the handler is kept current.
  • Fixed the order lists not reloading when the pair changed.

One order-history request per order, from inside a state update

When a frame reported orders that had gone terminal, the standard panel asked for the full closed-order list once for every one of them — and did it from inside a state update, which is not a place a request may be issued from at all. A bot cancelling and re-placing a ladder puts many terminal orders in one frame.

  • Fixed the order history being re-requested once per terminal order in a frame instead of once per frame.
  • Fixed an order that filled the instant it was placed — and so never appeared in Open Orders — not reaching the Order History tab until something else happened to reload it.