Bicrypto 6.4.4

14 June 2026

HUMMINGBOTCUSTOM-CHAINSECOSYSTEMWALLETDEPOSITSKYCPHONESECURITYBUG-FIXES

Core v6.4.4

Release Date: June 14, 2026 Tags: HUMMINGBOT, CUSTOM-CHAINS, ECOSYSTEM, WALLET, DEPOSITS, KYC, PHONE, SECURITY, BUG-FIXES

Overview

Version 6.4.4 is a major feature release built on two new pillars. The first is a first-class Hummingbot connector — operators can now run automated spot and perpetual market-making strategies against the platform through a Binance-shaped, HMAC-authenticated API, complete with per-key audit logging and admin key management. The second is custom EVM chains — operators can add any EVM-compatible chain from the admin panel, validate it with a built-in connectivity tester, and have deposits and withdrawals run on the same pipeline as built-in chains. Alongside these, the release closes a number of money-touching ecosystem wallet/deposit bugs, fixes a class of KYC bugs that blocked fully-verified users from trading and made admins see "not submitted," and standardizes phone-number handling on E.164 across the entire product.

Update Instructions

After updating, run the following command in terminal:

pnpm updator

Added

Hummingbot connector

Spot and perpetual trading via Hummingbot

Bicrypto now ships a first-class connector for the Hummingbot market-making bot, exposing a Binance-shaped REST and WebSocket API under /api/hb. Operators can run automated spot strategies against the ecosystem CLOB and perpetual/futures strategies against the futures engine, with LIMIT and MARKET order placement, cancellation, and status lookup, plus per-symbol leverage and live position listing. Market data is served through public, unsigned endpoints — ping, time, exchange-info, ticker, trades, orderbook, and perp funding-rate — so the bot can bootstrap trading rules and quote off real liquidity. A single multiplexed WebSocket at /api/hb/stream carries public spot/perp book, trade, ticker, depth, mark-price and funding channels, plus signed private userOrders, userBalances, userPositions, and userTrades streams.

Per-key HMAC authentication with an audit log

Every trading request is authenticated with an HMAC-SHA256 signature over method\npath\ntimestamp\nnonce\nbody, carried in X-API-Key, X-Timestamp, X-Nonce, and X-Signature headers. Timestamps must fall within a ±10s receive window and nonces are single-use (replay-rejected via Redis), so a captured request cannot be re-sent. Users self-manage keys (create, list, update, rotate, enable/disable, delete) from a new Hummingbot API Keys menu entry; key minting and rotation require KYC Level 2 and a real login session. A new audit log records auth failures, replay/IP blocks, disabled-key hits, and trade placements/cancellations for after-the-fact diagnosis.

Admin key management and rate limiting

Admins get a paginated view of every Hummingbot-capable key on the platform — owner, scopes, last-used IP, and disabled state — gated behind new view.hb.key / edit.hb.key permissions. Admins can remotely disable (kill-switch), re-enable, and set per-key rate-limit overrides. Both signed endpoints (per key) and public market-data endpoints (per IP) are throttled by Redis fixed-window counters, returning HTTP 429 with a reset hint when exhausted.

Connector, presets, and documentation

The Python bicrypto and bicrypto_perpetual connectors, a tuned PMM controller, ready-made PMM/XEMM config presets, a Postman collection, stress tests, and upstream-submission material are included, alongside SETUP, STRATEGY_GUIDE, TROUBLESHOOTING, and soak-run docs.

Design choices worth knowing

  • Byte-exact HMAC with timing-safe comparison; the signature is verified before any key-state check, so holders of only the public key can't probe state or spam the audit log.
  • Replay protection via single-use nonces in Redis (TTL 2× the receive window).
  • Key rotation returns the new secret exactly once and instantly invalidates the old one; the secret is write-only and never serialized into list/update responses.
  • Deny-by-default IP allowlisting; X-Forwarded-For is only trusted behind an explicitly declared proxy (HB_TRUST_PROXY).
  • Leverage×amount correctness: perp quantity is treated as the true position size (margin = notional ÷ leverage), divided by the engine's leverage factor before persistence so stored size matches the request; per-market leverage ceilings are enforced.
  • Duplicate clientOrderId rejection before placement to keep the bot's in-flight tracking consistent.

Custom EVM chains

Add any EVM-compatible chain from the admin panel

Operators can now register their own EVM chains entirely from Admin → Ecosystem → Custom Chain, no code or env edits required. A new card-based management page lists every custom chain with live status, and a dedicated create/edit form captures everything the platform needs: chain symbol, display name, EVM chain ID, native currency and decimals, network name, HTTP RPC URL, optional WebSocket RPC URL, public explorer URL, Etherscan/Blockscout-compatible explorer API URL and key, deposit confirmations, balance precision, and an icon path. Chains can be enabled, disabled, edited, or deleted in place, and the registry re-hydrates immediately after every change.

Built-in connectivity tester validates endpoints before you save

A new connectivity test probes a chain's RPC, WebSocket, explorer, and explorer-API URLs in parallel and reports per-endpoint status, latency, and live block height — all read-only, nothing is stored. It verifies the RPC's reported chain ID matches what you configured, normalizes the explorer API base to the exact …/api shape the transaction fetcher uses, and probes the specific RPC methods each flow needs to produce a readiness summary (Balances, Native deposits, Token deposits, Withdrawals, Realtime watching). You can run the test from both the create/edit form and per-chain on the list, catching a misconfigured node before it ever goes live.

Deposits and withdrawals run on the same pipeline as built-in chains

Custom chains are hydrated into the provider, deposit-monitor, and balance systems per worker thread, so they use the same infrastructure as built-in chains. Both provider caches are cleared on every edit so changes take effect without a restart. The native deposit monitor uses the explorer API when one is configured and automatically falls back to direct RPC block scanning for chains without an explorer. Pending deposits now honor each chain's configured confirmation depth before crediting (guarding against reorg double-credits) and finalize even when no one has the deposit page open; reverted or long-dropped transactions are retired instead of polled forever.

Native-coin handling, safe edits, and seeding

Because a chain's native coin (e.g. PBX) has no contract address, it can't be imported through the normal token flow — so the platform now auto-creates and keeps it in sync as a native ecosystem token for that chain, updating currency, network and decimals on edit. Disabling or deleting a chain deactivates its tokens so users stop receiving deposit addresses nothing monitors. Guard rails block redefining built-in or reserved chain symbols, reusing an existing chain ID, and deleting or renaming the currency of a chain whose native balance users still hold. Payload validation returns clean errors for out-of-range fields, and the default seed chain runs exactly once per install (a deleted default no longer resurrects on restart).


Changed

Phone numbers — global E.164

One canonical format everywhere

A previous release fixed international phone handling on the security profile's phone-verification tab, but the rest of the app still used a patchwork of US-only and free-form validators. Phone handling is now centralized on one canonical format — E.164: a leading + followed by 7–15 digits — and applied everywhere a phone number is entered: registration / merchant onboarding, the profile personal-info tab, the KYC dynamic-form phone field, SMS two-factor setup, e-commerce checkout, and the admin user create/edit and order-shipping forms. Inputs normalize as you type (keep the +, strip everything else, cap at 15 digits) and reject anything that isn't a valid international number.

Backend validators reconciled

Several backend validators contradicted each other and the new standard: the admin user form demanded exactly 10 digits with no +, and the e-commerce shipping address required digits only (rejecting the +), which would have blocked checkout the moment a stored phone carried a country code. All of these now accept canonical E.164, and every server-side write path — profile update, admin create / edit / CSV import, phone & 2FA SMS send, and merchant / order creation — normalizes the number before saving.

Twilio send path left strict (by design)

The outbound-SMS validators were intentionally left at the stricter E.164 form Twilio expects, rather than loosened to the input rule. The wider input rule is for capture, storage, and display only — so a number that's accepted in a form can't slip through to Twilio in a shape it would reject at send time.


Fixed

Ecosystem wallet and deposits

Withdrawals no longer silently underpay

Previously, when an on-chain balance couldn't cover both the requested amount and the network gas fee, the EVM withdrawal path quietly reduced the amount sent and let it through. Because the user's platform balance had already been debited the full amount (with gas charged separately after confirmation), the difference was unrecorded user loss. Withdrawals in this situation now fail cleanly so the queue refunds them, and the error tells the user to request a smaller amount that leaves room for the fee.

Native withdrawals work on chains without a master wallet

Native-coin withdrawals are signed by the user's own deposit address and need neither a token contract nor the master-wallet gas payer, but the old code always loaded the master wallet first — making native withdrawals fail on any chain that didn't have one. The withdraw path now resolves only the token metadata for native sends, and rejects unsupported or disabled chains up front with a clear message.

Accurate "max withdrawal" amounts

The max-withdraw estimator used a flat minimum fee and pointed at a fee provider that didn't exist, so the on-chain gas estimate never ran and every figure fell back to a hardcoded 0.0001. It now computes the platform fee the same way the withdraw submission does (percentage vs. minimum, whichever is larger) and uses the real provider to estimate network fees, so the returned maximum actually passes when submitted.

More reliable deposit detection and confirmation

Several deposit-monitoring bugs were fixed. The background deposit scanner was calling the raw explorer fetch and checking the wrong status field, so it could never detect anything; it now parses transactions correctly and matches confirmed status. Pending-verification was rewritten to honor each chain's required confirmation depth before crediting (guarding against reorg double-credits), to stop burning retry attempts on transactions that are merely still pending, to drop reverted or 48-hour-stale transactions, and to keep finalizing deposits even when nobody has the deposit page open. EVM deposit monitoring now falls back to scanning blocks directly over RPC when a chain has no explorer or its explorer starts failing, surfaces dead RPC providers as real errors instead of a silently-stopped monitor, and re-arms a fresh monitor for a user's next deposit instead of reusing a completed one. A new once-a-minute "Ecosystem Deposit Verification Watchdog" cron picks up deposits stranded by a server restart or a closed browser.

Master wallet keys no longer written to disk

Master wallet creation previously wrote a plaintext backup file containing the mnemonic and private key alongside the encrypted database row. That file is no longer written — the encrypted DB row is the only persisted copy — so a file-read vulnerability or leaked backup can no longer drain the master wallet. Creating a master wallet for an unknown or disabled chain is now rejected before any key material is generated.

Correct orderbook accounting on cancellation

Cancelling an ecosystem order (individually or via cancel-all) subtracted the order's original amount from the aggregated orderbook price level. Because every prior fill had already decremented that level, this double-counted fills and could wipe out other users' resting liquidity at the same price. Cancellation now subtracts only the unfilled remainder, matching the matching engine's own behavior.

KYC verification and feature access

Fully-verified users were blocked from trading

The effective-KYC check dropped any approved application whose verification level could no longer be resolved. Because levels are hard-deleted while applications are soft-deleted, a deleted or re-created level can orphan an approved application — and when that happened, a genuinely Level-3-approved user was treated as completely unverified: the trade page showed the "Complete Verification" gate and the admin panel showed "not submitted." Approved applications are now kept even when their level association is missing, recovering the level number from whatever the record carries, so verification survives level edits.

The "Complete Verification" dead-end loop

When an approved user merely lacked the specific feature a page required (e.g. the granular "trade" feature), the gate still rendered a "Complete Verification" button linking back to a KYC page already showing 100% complete — a loop with no way forward. The trade gate now routes through the same normalized store helpers every other gate uses, and the notice distinguishes "you still need to verify" from "your level doesn't include this feature," showing accurate copy and a View Verification Levels action (with a contact-support hint) instead of the misleading prompt.

Admin showed "verification not submitted" for verified users

The admin user pages expected a single effective verification status, but the user detail and user list only returned the raw list of applications — so the KYC badge, the account-summary card, and the verification-progress bar always rendered "not submitted" regardless of real status. Both now compute the same effective KYC status the user-facing profile uses, so the admin view matches reality.

Other fixes

Native-coin token imports

Native coins have no smart contract, but the token importer required a contract address and rejected them. The importer now accepts native imports, filling a standard null-address sentinel automatically, and returns a clear 409 ("chain already has a native token registered" / "contract already exists") instead of a raw database error on duplicates.

Background job and worker fixes

Repeatable cron jobs no longer retain their completed-job history in Redis forever — high-frequency jobs were bloating Redis to multiple gigabytes and timing out commands; retained history is now bounded. Custom-chain hydration now runs in worker threads as well as the main thread, so worker-served requests no longer return "unsupported chain." Deposit providers can now be explicitly cleared from the shared cache so RPC-endpoint changes and reconnects take effect without a restart.

Hardened WebSocket identity

WebSocket connections can now opt out of being keyed by user id, so each connection gets a unique server-generated id, preventing clients from colliding with or evicting each other's registration by guessing a user id. The peer's socket address is now also exposed for routes that enforce per-key IP whitelists.