Connections
The venues × Sim/Demo/Live credential grid, the live Status column, the masked editor behind the one sanctioned credential write, per-venue accounts, and the remote-backend registry.
The Connections window is crates/vike-connections/src/lib.rs: the venues × Sim/Demo/Live
credential-status grid — which venues have API keys configured in the project's credential store —
plus in-app editing of those keys and a live per-venue connection-status column. status is the
pure enumerator, env_write the write, and view the egui render that vike-desktop mounts as the
tool window. The body that wires it is
crates/vike-app-core/src/tool_views/connections.rs, which also hosts the remote-backend picker,
editor and settings sections described below.
The grid
The row roster is crates/vike-connections/src/status.rs's VENUES, which is
vike_catalog::BRIDGE_VENUES — one list, so a new bridge appears here without a second edit. For
every venue that follows the generic {VENUE}_{ENV}_API_KEY / _API_SECRET naming the enumerator
reads through vike_bridge_core::credentials::load_credentials_from, the single naming authority;
venues whose bridge reads a bespoke shape get a per-venue override that reads the exact names that
bridge's own loader reads. The header is blunt about why: falling through to the generic grid is a
claim, and when it is false the grid disagrees with the mount in both directions — a green dot
beside a venue vike_mount::make_engine will leave on paper, and no dot beside one it will arm.
Alpaca, cTrader, IBKR and Polymarket each sat in that fallback once while reading none of those
names.
The store is re-read fresh by the binary every frame the tool is visible; the body's doc calls a per-frame parse of a small file cheap, and it is what keeps the grid live after a save or an external edit.
The Status column is the runtime counterpart. crates/vike-model/src/feed_status.rs's
parse_feed_status classifies each bridge feed's own status string into ConnectionState —
Unknown, Disconnected, Connecting, Connected or Error — in a fixed order: disconnected
first, then the error family, then the connected family, then the connecting family. The map the
app passes covers every streaming feed (binance, bybit, okx, aster, hyperliquid, polymarket); a
venue with no live producer yet — deribit, the FX and broker venues — is absent and always renders
Unknown, never guessed. It is the same classifier the status strip's dot and the headless daemon's
health gate read.
The editor, and the one write it makes
crates/vike-connections/src/view.rs lists the non-negotiables. An existing secret's plaintext is
never read back into the UI — edit fields are egui::TextEdit::password and start empty, and the
dot is the only feedback that something is configured. Only non-empty fields are written; an empty
field means leave unchanged. No secret value is ever passed to a log — only the venue and tier.
Save goes through crates/vike-connections/src/env_write.rs's save_credentials_journalled: the
store write is vike_secrets::save_credentials, whose upsert_env transform
(crates/vike-secrets/src/env_write.rs) replaces matching KEY=value lines in place, appends
keys that were absent, preserves every comment, blank line and their order verbatim, and lands the
result atomically by temp file and rename. That module's header names the rule it enforces: nothing
may regenerate, reorder or clobber the store, because it is the user's only copy of live venue keys.
The journalled wrapper then appends a credential_write record to the change journal — key names
only, and it cannot record a value because Change::credential_write has no parameter for one. The
store write happens first and its error is returned; a journal failure is logged at error and
never fails a write that landed.
One walk decides where Save lands
CredentialHome::resolve derives both the store path and the journal from the boot's own
settings_dir and state_dir. Its doc records why: the Save arm used to find the store by a
$VIKE_SETTINGS_DIR-blind walk while the grid rendered from a read that honoured the override, so on
a deployment naming its settings directory the editor showed one project's keys and Save wrote
another project's file, silently. See Settings.
Accounts
A venue may hold more than one account, and account_strip in view.rs puts that dimension in a
selector above the grid rather than as more rows or more columns, so the table's shape is constant
in the number of accounts and a box with one account renders exactly the panel that shipped. The
default account is always offered first. Add account takes a label and writes nothing — an
account comes into existence when its first credential is saved, which is the rule the read side
already obeys. There is deliberately no Remove: it could only be implemented by deleting lines from
the store, so the panel renders an instruction naming the file instead. Every key name is composed
through vike_model::account_keys::account_key, which appends __{LABEL} after the whole of
today's key and returns the default account's names unchanged; Accounts
carries the grammar.
Arming a venue is not done here. The Data Manager's Venues tab shows each venue's mode, credentials and effective arming and carries the switch — see Data Manager and Risk and arming.
Backends
Below the grid sits the remote-backend picker. crates/vike-app-core/src/backend_registry.rs keeps
backends.json beside the workspace file: one BackendRecord per daemon with a display name, a
dial address, and the credential-store key names of its observe and control keys — never key
material, because a GUI-written JSON file would be a second, ungated copy of a live key, and a name
is auditable by eye against vike-cli secrets list where a value is auditable by nothing. The
address is the daemon's dial address, not config.tradehub_addr, which is its bind address. Each
record's control flag is a per-backend arming gate: with it false, or no control key named,
resolve_keys never yields a control key. Rows render with an Active marker and one
Connect/Disconnect button; clicking the active row disconnects, any other row connects, and
switching_available makes the buttons inert while a local trading core runs.
crates/vike-app-core/src/backend_editor.rs adds Add, Edit and an are-you-sure Delete. Validation
runs before the save so a hostile name is refused visibly rather than silently renamed; deleting the
active backend disconnects first; editing it takes effect on the next connect. key_presence is a
read-only membership check of the typed name against the credentials map — present or absent, never
a value.
The Backend settings section (crates/vike-app-core/src/tool_views/backend_settings.rs) fetches
the active daemon's effective settings rows over the wire and lets an operator edit them; a
policy.toml row's Save stays disabled until the exact dotted key has been typed into a confirm box
that is never pre-filled, the daemon enforces the same rule server-side, and an accepted write
answers restart-required — the running backend keeps its boot-time values until restarted. Against a
daemon that predates the verb, the section says so. How the observer connects at all is on
Observe mode.
The cockpit
The Polymarket scalp cockpit — the rolling-window chain rail, the Price-to-Beat header, the one-click ticket with its arm switch, and the probability ladder over integer-cent rungs.
Observe mode
vike-desktop --observe against a headless daemon — the one mode the shipped binary can compose, the two the library still declares and nothing reaches, the self-healing bridge, and the control channel that can place real orders.