vike
Guides

Arm one venue for demo

Two gates stand between a credential and a live socket, and the ceiling is the one consulted first.

By default nothing on the box trades anything real. Getting one venue onto its own demo account is two edits in two files, in a fixed order: a ceiling in policy.toml naming which venues this deployment means to trade, and credentials in the store deciding whether the venue can reach that tier. The ceiling is read first, which is the usual reason a store full of keys still mounts paper.

1. Write the ceiling

crates/vike-mount/src/lib.rs's make_engine is the composition root, and its header states the order: the deployment's per-venue arming ceiling — policy.venues.<venue> — is consulted first, and "a paper venue returns the paper client having loaded no credential, fetched no instrument grid and opened no socket". Only then does the older rule apply, absent-credentials-is-the-live-gate.

# <project>/settings/policy.toml
[venues]
binance = "demo"

The three tiers are paper < demo < live (crates/vike-config/src/venue_mode.rs's VenueMode), declared in ascending risk order so the Ord derive follows the declaration rather than a comment. demo is "the venue's own demo/testnet/sandbox account — real wire, real rejections, no real funds".

A ceiling only ever refuses

The fold is VenueMode::cap, and its module doc is emphatic: min(mode, whatever the existing mechanisms decide) — never max. A venues.bybit = "live" line does not put bybit live; it "declines to stop bybit going live if its credentials, its {VENUE}_MAINNET flag and its mount arm all already say so". Arming still takes the credentials. The ceiling can only take them away.

The default is a filled map, one paper row per roster venue, not an empty one: the safest answer for a machine with no policy.toml. Policy is also the one settings type with no environment layer at all — it implements neither EnvOverride nor CliOverride, both sealed, so policy.apply_env(&env) does not fail a review, it fails to compile (crates/vike-config/src/policy.rs). See Settings.

If your box already had credentials and has never written a [venues] table, the first mount prints a paste-ready block naming every venue that has credentials and is now paper (crates/vike-mount/src/paper_fallback.rs's venue_arming_migration_message, latched to fire once per process). Writing the table at all silences it, whatever the values — including all paper, "which is a decision like any other".

2. Put the demo keys in the one store

There is one file and no precedence:

<project>/settings/secrets.env

crates/vike-secrets/src/lib.rs is the authority — "point at the file, edit the file". <project> is resolved at runtime by walking up for a project marker, and VIKE_SETTINGS_DIR names the settings directory outright — the level holding secrets.env, not <project> above it. Ask the binary rather than guessing:

vike-cli secrets path       # where it resolved for THIS invocation, and its exposure
vike-cli secrets template   # the key grid, empty values, to stdout
vike-cli secrets list       # key NAMES only, never a value

vike-cli secrets is read-only by construction, and template has deliberately no --out flag: "the moment this command owns a path it can truncate a live store" (crates/vike-cli/src/cmd/secrets.rs). Creating the file is your editor's job; redirect the template into it yourself.

The names are {VENUE}_{SIM|DEMO|LIVE}_API_KEY / _API_SECRET / _API_PASSPHRASE, composed from vike_model::credential_keys' suffix and tier tables rather than spelled at each call site. FX venues have bespoke shapes, and more than one account per venue appends __{LABEL} after the whole of today's key — see Accounts.

Required is per-venue, and OKX is the reason

key + secret is the required set for binance, bybit and deribit; OKX additionally requires _API_PASSPHRASE, because its signer sends one on every request. A store with two of the three resolves None and the venue stays paper exactly like an unconfigured one — the correct outcome and an invisible one, which is why crates/vike-bridge-core/src/credentials.rs's missing_required_passphrase names the missing variable out loud at the mount.

Absent credentials are the live gate: no store means an empty map, every venue loader returns None, every venue stays paper. A store that exists and cannot be read is the opposite case and errors, because "not configured" and "cannot open" must never look the same to an operator.

3. Check before you start

vike-cli config check

crates/vike-cli/src/cmd/config_check.rs resolves the same directory through the same loader as config show and hands back an exit code, so it can sit in a unit's ExecStartPre=. Its levels are arguments, not tuned severities: an absent store is ok (that is the live gate), a VIKE_SETTINGS_DIR naming a non-directory is a failure (set-but-unhonoured), and an unreadable store is a warning that becomes a failure only on a box armed for live.

Why it is still paper

crates/vike-config/src/venue_arming.rs's ArmingBlock exists to answer exactly the complaint "I set live and it is still paper", one observable cause per variant with a distinct response: Disarmed (the ceiling), NoCredentials (the store), FeatureAbsent (this binary has no arm — the ibkr, polymarket and fxcm features), MainnetSwitchUnset ({VENUE}_MAINNET is a conjunct of a live ceiling, never a replacement for it), LiveOnlyArm (Polymarket runs no testnet) and SdkAbsent (FXCM without its linked SDK).

Do not arm mainnet from the credential file

crates/vike-config/src/arming.rs refuses startup when a {VENUE}_MAINNET line in secrets.env carries the arming value — the exact string 1, after a trailing # comment is stripped and whitespace trimmed; 0, empty and true arm nothing at any reader and are ignored rather than refused. The file is KEY=value, last wins, and an append needs no read permission — so a line nobody re-reads could flip a venue from demo to mainnet. Refusing rather than ignoring is deliberate: an operator who wrote the line believes they are on mainnet, and a build that quietly traded demo would have them reading demo fills as real ones.

With the ceiling written and demo keys in place, the mount takes the venue to its demo tier. What the venue can then do is its own generated page under venues; what a first live order is checked against before it leaves is startup preflight and risk and arming.

On this page