Install and enable

Turning the Futures addon on — the Ecosystem and ScyllaDB prerequisites, the extension row, the environment variables nothing writes for you, how to confirm the matching engine took the lease, and how a trader funds a futures wallet.

6 min readUpdated 3 August 2026install, scylladb, ecosystem, cron

Futures is a licensed addon that installs into the same tree as core. There is no separate service and no separate database user. What there is, and what catches people out, is a chain of three things that must all be true before a single order can be placed: Ecosystem present, ScyllaDB reachable, and the matching engine actually running on a process that is allowed to own it.

Before you start

    • Bicrypto core installed and running (three PM2 processes, Redis up)
    • The Ecosystem addon installed and enabled
    • ScyllaDB installed, running, and reachable on port 9042 from the app box
    • Your CodeCanyon username and the Futures purchase code
    • Shell access — enabling an extension needs a backend restart

The core installer does not mention ScyllaDB anywhere, and none of its settings are in .env.example. You install the server, open the port, and add the variables by hand. The client creates its own keyspaces and tables on first connection, so there is no schema to import — but if Scylla is not there, the futures engine logs a warning at boot and every position endpoint answers 503.

Enable the extension

  1. Activate the licence — in the admin panel go to System → Extensions, find Futures, and enter your CodeCanyon username and purchase code. The box needs outbound HTTPS for this.

  2. Install and enable — install the latest version, then switch the extension's toggle on. This writes the futures row in the extensions table; nothing else about the platform changes yet.

  3. Add the ScyllaDB settings to .env — if you already run Ecosystem, most of these exist. SCYLLA_FUTURES_KEYSPACE is the one that is specific to this addon.

    SCYLLA_ENABLED="true"
    SCYLLA_CONNECT_POINTS="127.0.0.1:9042"
    SCYLLA_DATACENTER="datacenter1"
    SCYLLA_KEYSPACE="trading"
    SCYLLA_FUTURES_KEYSPACE="futures"
  4. Restart the backend — extension detection happens once, at boot. The backend reads the enabled extensions, and only then decides whether to start the futures matching engine.

    pnpm restart
  5. Confirm the engine started — see the verification section below. This is the step people skip, and it is the one that decides whether leveraged positions are marked at all.

What enabling actually starts

Switching the row on has three separate effects, and they land in different places.

The routes appear. Everything under /api/futures and /api/admin/futures becomes reachable, and the three admin screens (Dashboard, Markets, Positions) join the admin menu. The Futures Orders table appears under Finance → Orders rather than in the Futures menu.

The Scylla keyspace is created on first connection. Four tables — orders, position, orderbook, candles — plus five materialised views, in the keyspace named by SCYLLA_FUTURES_KEYSPACE. You never run DDL yourself.

The matching engine boots — on exactly one process. At start-up the backend checks extensions.has("futures") and that it is the main thread, then starts the futures engine. The engine claims a leadership lease named futures-matching; the process that wins it owns the order queue and arms a two-second mark sweep that re-marks every open position, fires stop-loss and take-profit, and liquidates. A process that loses the lease serves tickers and refuses every mutating call.

The mark sweep is the only thing that closes a losing position. It runs on the lease holder and nowhere else. A sweepFuturesPositions cron exists as a 60-second backstop, but on a dedicated cron process (CRON_MODE=only) that process is structurally refused the lease, so its sweep returns immediately and does nothing. If your web process never boots the engine, positions sail past their liquidation price indefinitely.

Check the backend log at boot for the futures engine claiming the lease. If you see only "Ecosystem extension not available, futures matching engine disabled", the problem is Ecosystem or Scylla, not Futures. See Engine and storage for how the lease is arbitrated and Troubleshooting for the symptoms of a leaderless deployment.

The cron jobs it registers

Three jobs appear under System → Cron once the extension is on.

Job Period What it does
sweepFuturesPositions 60s Backstop mark sweep — re-marks every open position, enforces stops, liquidates. A no-op unless this process holds the lease.
reconcileFuturesPositions 5 min Replays Scylla status writes for positions whose wallet credit committed but whose Scylla write failed. Never touches wallets.
reconcileFuturesOrders 5 min The same replay for orders.

The reconcilers exist because every settlement path here is MySQL first: the trader's money moves inside a MySQL transaction, and only then is the Scylla row flipped. If the second half fails, the money is already right and the reconciler catches up the row. That ordering is why a position occasionally shows OPEN for a few minutes after a payout — and why you must never "fix" one by hand.

Give traders a fundable wallet

Futures margin lives in a FUTURES wallet, always in the quote currency of the market. It is not the spot wallet and it is not the ecosystem wallet.

The transfer matrix allows ECO → FUTURES and FUTURES → ECO and nothing else. A trader with a balance in SPOT or FIAT must move it into ECO first. Attempting FUTURES → SPOT is rejected with "FUTURES wallet can only transfer to ECO wallet".

So the funding path a trader follows is:

  1. Deposit (gateway, or an on-chain Ecosystem deposit) into a SPOT, FIAT or ECO wallet.
  2. Transfer → ECO, if they are not already there.
  3. Transfer ECO → FUTURES in the quote currency of the market they want — USDT for a BTC/USDT contract.

The wallet is created on first transfer; there is nothing to provision.

Gate it behind KYC, if you want to

Futures trading has its own KYC feature flag, futures_trading. Add it to a verification level under CRM → KYC, and the order route will refuse to place an order for anyone below that level. The gate runs on order placement only — closing a position and cancelling an order stay open, so raising the requirement never traps a trader's money in an open position.

Verify the install

/admin/futures loads a dashboard, /admin/futures/market an empty markets table, /admin/futures/position an empty positions table. If the menu entries are missing, the extension row is not enabled or the frontend has not been restarted.

GET /api/futures/market should return [] rather than an error. A 503 here means Ecosystem is missing or Scylla is unreachable.

cqlsh -e "DESCRIBE KEYSPACES"

You should see the keyspace named by SCYLLA_FUTURES_KEYSPACE alongside Ecosystem's. If it is absent, the engine never connected.

Create a market, place two crossing orders from two test accounts, and watch a position appear at /admin/futures/position with status OPEN. Then check that GET /api/futures/position?type=OPEN_POSITIONS returns a liquidationPrice. If positions open but never liquidate, the lease is the first thing to check.

Next

Create your first market — Futures markets walks the three-step wizard and explains what each metadata field does to a live order.

The platform's built-in database backup covers MySQL only. Your futures orders, positions, order book and candles are all in ScyllaDB, which has no backup path in the product at all. If you run this addon, you own Scylla's backups. The only futures data in MySQL is the futures_market table — the market definitions, not a single trade.