Skip to main content

Web app

The frontend is a React + Vite single-page app (web/) with an editorial "1900 mathematical monograph" design — paper/indigo palette, Fraunces serif headings, monospace tabular numerals, and a payoff canvas. It is deployed at bachelier-frontend.vercel.app.

Chain-direct mode

The app reads price / vault / position state in two tiers:

  • API mode — if VITE_API_URL points at a deployed REST API, the app uses it for richer history, charts, and trailing APY.
  • Chain-direct mode — if VITE_API_URL is unset (the production default), the app reads vault state, the BTC price, and per-user positions straight from a Stacks node via read-only calls (lib/chainRead.ts). No backend required.

This is why the Vercel deployment needs only the static frontend.

Configuration

All env access is centralized in web/src/lib/config.ts:

VariablePurpose
VITE_STACKS_NETWORKdevnet / testnet / mainnet (production defaults to testnet)
VITE_BACHELIER_DEPLOYERdeployer principal → bakes live contract ids into the bundle
VITE_API_URLoptional REST API base; unset → chain-direct
VITE_ENABLE_FAUCETforce-show the mock-token faucet (auto-on when tokens are the mocks)

Wallet flows

The app uses @stacks/connect v8 and builds every user transaction with explicit post-conditions (via the Pc fluent builder) so the wallet guarantees exact token movements:

  • Faucet — mints 1 sBTC + 10,000 mock USDC to the connected wallet (mint(amount, recipient), allow mode).
  • Depositdeposit(amount, sbtc) with Pc.principal(you).willSendEq(amount).ft(sBTC).
  • Withdrawwithdraw(shares, sbtc) with a "vault sends ≥ 1 sat" post-condition.
  • Buy callbuy-call(contracts, usdc) with a willSendLte(maxPremium) slippage guard (premium × 1.02).
  • Claim premium, exercise, request/cancel withdraw — corresponding guarded calls.

The browser is the only signer of user-fund transactions; the app never sees a private key.

Try it

  1. Open the app; the BTC price pill and vault stats populate from the testnet node.
  2. Connect Leather or Xverse (set to testnet).
  3. Click Faucet to mint mock sBTC / USDC.
  4. Deposit sBTC → receive bcSHARE; your position card and the round countdown appear.

The 60 test users performed exactly this deposit flow (scripted with their own keys), so the live vault already shows real collateral and shares.