Skip to content

feat(accounts): fast add-credential with immediate balances + background bring-up#171

Closed
fengtality wants to merge 2 commits into
mainfrom
feat/fast-hyperliquid-add-credential
Closed

feat(accounts): fast add-credential with immediate balances + background bring-up#171
fengtality wants to merge 2 commits into
mainfrom
feat/fast-hyperliquid-add-credential

Conversation

@fengtality

Copy link
Copy Markdown
Contributor

Problem

Adding a connector credential blocks on the full trading-connector bring-up before returning. For Hyperliquid perp that is ~85s — a metaAndAssetCtxs call per HIP-3 DEX in both symbol-map init and trading-rules update, plus order-book / websocket startup waits. The result:

  • the UI sits on "Saving credentials…" for up to a minute, and
  • the new connector's balances only appear a refresh loop later (and a full update_account_state() over all connectors — including an unreachable Gateway — ran on every add).

Change

Split the trading-connector bring-up into a fast part (balances only) and a heavy part (the rest), and finish the heavy part in the background.

  • update_connector_keys now creates the connector, fetches balances only (mirroring the Hummingbot CLI connect), caches it, and schedules the heavy bring-up (symbol map, trading rules, HIP-3 markets, positions, recorders, network) in the background — in place on the cached connector, so it becomes trade-ready without blocking the response or flickering the portfolio. Bad keys still fail fast here and the caller deletes the credential.
  • _create_and_initialize_trading_connector keeps the exact same end state by calling the new _finish_trading_connector_init after the fast balances fetch.
  • add_credentials surfaces the new balances immediately via a scoped update_account_state(account_names=[…], connector_names=[…], skip_gateway=True) instead of a full all-connectors / Gateway refresh. It's wrapped in its own try/except so a display-only refresh failure can never delete a just-validated credential.

Correctness

  • Delete-race guarded: the background task checks list_available_credentials before and after finishing, and tears the connector back down if the credential was removed meanwhile — so a removed key can't linger in the cache / account state / portfolio.
  • Background tasks are held in a module-level set so they aren't garbage-collected mid-run.
  • No public API or response-shape changes; the connector reaches the identical fully-initialized state, just asynchronously.

Result

"Saving credentials" returns in a few seconds and the new balances show up in the portfolio right away; the connector becomes fully trade-ready ~80s later in the background.

Test plan

  1. Add a Hyperliquid (perp + spot) credential via the API → response returns in seconds; balances appear on the next portfolio read.
  2. Within the background-finish window, confirm the connector is present with balances; after ~80s confirm it is trade-ready (trading rules / markets loaded).
  3. Add a bad key → still fails fast and the credential is deleted.
  4. Add then immediately delete a credential → it does not reappear after the background finish completes.

🤖 Generated with Claude Code

fengtality and others added 2 commits June 4, 2026 13:39
…und bring-up

Adding a connector credential previously blocked on the full trading-connector
bring-up before returning. For Hyperliquid perp that is ~85s (a metaAndAssetCtxs
call per HIP-3 DEX in both symbol-map init and trading-rules update, plus
order-book / websocket startup waits), so the UI sat on "Saving credentials…"
for a long time and the new balances only appeared a refresh loop later.

Split the bring-up into a fast part and a heavy part:

- update_connector_keys now creates the connector, fetches balances only
  (mirroring the Hummingbot CLI `connect`), CACHES it, and schedules the heavy
  bring-up (symbol map, trading rules, HIP-3 markets, positions, recorders,
  network) in the background, in place on the cached connector. Bad keys still
  fail fast here and the caller deletes the credential.
- _create_and_initialize_trading_connector keeps the same end state by calling
  the same new _finish_trading_connector_init after the fast balances fetch.
- add_credentials surfaces the new balances immediately via a scoped
  update_account_state(account_names=[...], connector_names=[...],
  skip_gateway=True) instead of a full all-connectors refresh, wrapped so a
  display-only refresh failure never deletes a just-validated credential.

Delete-race guarded: the background task checks list_available_credentials
before and after finishing and tears the connector back down if the credential
was removed meanwhile, so a removed key can't linger in the cache / portfolio.
Background tasks are held in a module-level set so they aren't GC'd mid-run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tion probe

validate_trading_pair() probes a pair by calling feed.fetch_candles() directly,
but fetch_candles() does not run initialize_exchange_data(). Feeds that resolve
exchange-specific symbol data there (e.g. Hyperliquid spot builds _coins_dict in
_initialize_coins_dict) then dereference uninitialized state in their REST
payload — `self._coins_dict[self._trading_pair]` raises
'NoneType' object is not subscriptable, which the endpoint wraps as
"Trading pair 'PURR-USDC' appears to be invalid on 'hyperliquid'".

Both /market-data/candles and /market-data/historical-candles gate on this
validation, so spot pairs failed on both the primary call and the fallback
(perp was unaffected — its payload uses the bare base asset). The real fetch
path get_historical_candles already initializes exchange data first; mirror that
in the validation probe.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fengtality fengtality force-pushed the feat/fast-hyperliquid-add-credential branch 3 times, most recently from f84963d to bd454b2 Compare June 5, 2026 12:58
@fengtality fengtality closed this Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant