Architecture
One contract inside NEAR Intents, plus a relay, a market maker and an oracle program.
Source: coming soon. Internal design notes are in docs/ in the repo.
Users fund a USDC balance in intents.near from any chain, buy with one signature, and are paid into the same balance after expiry and the dispute window. They can withdraw to any chain.
Components
| Component | Code | What it does | Run by |
|---|---|---|---|
| Options contract | contracts/options (Rust) | The rules and the money: holds collateral, mints option tokens, settles, pays out | NEAR, deployed once |
intents.near | near/intents | Holds every balance, settles trades atomically, cross-chain deposits and withdrawals | NEAR Intents team |
| Relay | apps/relay (TypeScript) | RFQ auction, submits matched trades, relays gasless collects | Us |
| Market maker | apps/mm (TypeScript) | Writes options, quotes, takes the other side, hedges | Us. Anyone can run another |
| Oracle WASM | oracle/ (Rust, wasm32-wasip2) | Median of 7 exchanges' 30-min averages, checked against Deribit | OutLayer TEE (mainnet), our proposer (testnet) |
| Market lister | apps/mm list | Keeps the next 4 daily expiries (plus a 4-hourly one on testnet) listed with BTC/ETH calls and puts around spot, each capped two strike steps out, writes inventory, burns unsold pairs after the write cutoff and redeems shorts once final | Us, with the market maker's key |
| Testnet proposer | apps/mm propose | Runs the pinned oracle WASM in wasmtime and proposes its price as the manual oracle | Us, testnet only |
| Mainnet settler | apps/mm settle | From 5 min after expiry, calls request_settlement every 10 min until a price is proposed or the oracle window closes | Us, with the relayer's key, mainnet only |
| Settlement monitor | apps/mm monitor | Checks every proposed price against Deribit, flags missing prices, watches the contract's NEAR reserve and pending oracle and owner changes | Us, read-only |
| Web app | apps/web (React) | Up/Down buying, positions, collect, deposits | Us |
| SDK | packages/sdk (TypeScript) | Series ids, payout math, fee-exact trade legs, intent payloads, signing, wire schemas | Library |
How they talk
web ──HTTP──▶ relay ◀──WebSocket── market maker ──▶ Deribit (prices), Hyperliquid (hedge)
│ │
│ sign └─ execute_intents([mm half, user half]) ──▶ intents.near ◀──▶ options contract
└──────────────────────────────────────────────────────────▶ (user deposits, balances)
options contract ── request_settlement ──▶ OutLayer TEE ── runs oracle WASM ──▶ 7 exchanges (+ Deribit check)Flows
| Flow | Steps |
|---|---|
| Fund | 1Click deposit from any chain (the quote goes through the relay's POST /deposit-quote, which adds our partner key), or ft_transfer_call into intents → USDC in the user's intents balance |
| Write (market maker) | Signs an intents transfer of USDC collateral (the most the options can pay) to the contract with {"action":"write"} → the contract mints long + short into its intents balance |
| Buy or sell to close | Web asks the relay for a quote → market makers bid → user signs their half → relay submits both halves in one execute_intents → USDC and option swap atomically |
| Settle | From 5 min after expiry our settler (mainnet) or anyone calls request_settlement → OutLayer runs the oracle → price proposed → final after the dispute window |
| Collect | Holder sends longs back with {"action":"exercise"}, pre-signed at buy time (auto-collect) or via the Collect button. The relay submits it; the contract pays from locked collateral into the holder's intents balance |
Money never leaves intents.near. User USDC and option tokens are intents balances, collateral is the contract's own intents balance, and payouts are intents ledger moves. There are no bridges, and we hold nothing.
Why our own relay
The official NEAR Intents quote bus needs a partner key and KYC for market makers, and doesn't list NEP-245 option tokens. Our relay does the same job for options and pays gas, so users never need NEAR.
Environments
| Mainnet | Testnet (live) | |
|---|---|---|
| Intents | intents.near | intents.near-options-dev.testnet, a copy of the exact mainnet wasm |
| Options contract | Not deployed | opt3.near-options-dev.testnet |
| Collateral | Native USDC | Mock USDC (6 decimals) |
| Expiries | Daily 08:00 UTC (Deribit's grid) | Every minute |
| Write and sell-back cutoff | 30 min before the end | 60 s before |
| Dispute window | 1 h | 2 min |
| Funding | 1Click from any chain | 100 test USDC a day from Add funds (relay POST /faucet) |
| Oracle | outlayer.near | outlayer.testnet. Manual oracle: near-options-dev.testnet, driven by the proposer |
Testnet ids are in deploy/testnet.json. RPC: https://rpc.testnet.fastnear.com.
Adding an asset
| Where | Change |
|---|---|
| Contract | The owner calls add_underlying(symbol, {index, decimals, min_write}). index is the Deribit index name, e.g. sol_usdc |
| Oracle WASM | Add one row to MARKETS in oracle/src/sources.rs, rebuild, host, set_oracle_wasm |
| Market maker, relay, web | Nothing. They read assets and series from the contract |
Deribit must list options on the asset, since the market maker prices from Deribit's volatility, and at least 3 of the oracle's 7 exchanges must list a spot pair.