Skip to content

Latest commit

 

History

788 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


Noether Logo

Noether

Decentralized Perpetual Futures Exchange on Stellar
Trade crypto perpetuals with up to 10x leverage — fully on-chain, powered by Soroban smart contracts.

Trade on Testnet »  ·  Docs »

Website · Documentation · Twitter · Discord · Telegram · Report Bug

License: MIT Stellar Testnet Built with Soroban Funded by SCF #41 Docs npm PyPI Twitter Follow Discord Telegram


Noether Trade Page

Table of Contents
  1. About The Project
  2. Features
  3. Live Demo
  4. Architecture
  5. How It Works
  6. Trading Parameters
  7. Built With
  8. Contract Addresses
  9. Project Structure
  10. Getting Started
  11. Roadmap
  12. Security
  13. License
  14. Team
  15. Acknowledgments
  16. Why "Noether"?

About The Project

Noether is a decentralized perpetual futures exchange (PerpDEX) built on the Stellar blockchain using Soroban smart contracts. Every order, match, and settlement lives on-chain — verifiable by anyone, custodied by nobody.

The protocol is funded by Stellar Community Fund #41 with a grant of $86,200 delivered across three tranches. Tranche 1 (trading engine) is complete and live on testnet; Tranche 2 (developer tooling, user-created vaults, on-chain referral) is code-complete with operator steps pending; Tranche 3 (mainnet launch) is underway — 14 trading pairs live on testnet and the full documentation site shipped.

Why Stellar?

~5s Finality Near-instant transaction confirmation
Sub-cent Fees Fraction of a cent per transaction
Soroban Rust-based smart contracts with WASM safety guarantees
Native USDC Circle-issued USDC with deep ecosystem support

(back to top)


Features

For Traders

  • Up to 10x leverage on 14 perpetual markets — BTC, ETH, XLM, SOL, XRP, ADA, BNB, TRX, HYPE, DOGE, ZEC, LINK, BCH, LTC
  • Isolated and cross-margin modes — per-position collateral, or a shared pool with account-level liquidation
  • Full order suite: Market, Limit, Stop-Limit, Stop-Loss, Take-Profit, Trailing Stop
  • Time-in-Force controls: GTC, IOC, Post-Only, plus a Reduce-Only flag
  • Volume-based fee tiers — 4 tiers over a 14-day rolling window, sub-basis-point precision
  • Funding rates that auto-balance long/short open interest, applied lazily on close/liquidate
  • Keeper-executed orders — limit, stop, and trailing orders execute on-chain without requiring you to be online
  • Multi-wallet support — Freighter, xBull, and other extension wallets via Stellar Wallets Kit, plus LOBSTR and mobile wallets over WalletConnect
  • On-chain referrals — register a code, share it, earn on-chain: a 4% referee discount and a 10% referrer fee share, applied in the market's fee path on every trade

For Liquidity Providers

  • Deposit USDC, receive NOE — the protocol vault's LP token (a SAC-wrapped classic Stellar asset)
  • Transparent AUM accounting: AUM = total_usdc + accumulated_fees − unrealized_trader_pnl
  • Fee share on every trade routed through the vault
  • Withdraw anytime — burn NOE, receive pro-rata USDC at current NOE price
  • User-created trading vaults (Tranche 2) — opt-in marketplace of leader-managed vaults as an alternative to the protocol vault

For Vault Leaders

  • Create a vault with one call to the on-chain vault_factory
  • Earn a 10% profit share above the high-water mark on depositor PnL
  • Trade on shared collateral via proxied leader_trade calls — depositors keep custody of their share token, you keep the upside
  • 5% min-holding invariant — leaders are required to keep their own skin in the game, enforced on-chain
  • Browse the marketplace at /vaults; manage your vault at /vaults/[id]/manage

For Developers

  • Documentation — user guides, REST + WebSocket reference, SDK quickstarts, and protocol docs at docs.noether.exchange
  • Public REST + WebSocket APIFastify gateway, OpenAPI auto-served at /docs. Wallet-challenge authentication issues bearer keys (currently closed-beta — see Security)
  • TypeScript SDKnoether-sdk on npm ships every endpoint plus WsClient with auto-reconnect and subscription replay
  • Python SDKnoether-sdk on PyPI mirrors the TS surface (httpx + websockets)
  • Soroban event indexer — captures every contract event into a Postgres projection table, ready for analytics
  • Shared @noether/tx-builders — single source of truth for Soroban transaction assembly across api + sdk-ts
  • Fully open source (MIT) — npm-workspace monorepo (api/, indexer/, sdk-ts/, packages/*) with vitest, CI, and Docker images for Azure Container Apps
  • Blue-green testnet deploys via scripts/deploy_staging.sh (deploy → verify → promote)
  • On-chain events — documented schemas matched exactly by the frontend parser
  • Optimized WASMopt-level = "z", LTO, panic = abort, stripped symbols
  • Shared math crate — fixed-point arithmetic in noether_common, no floating point anywhere

(back to top)


Live Demo

Trade on testnet in under a minute:

  1. Install Freighter Wallet and switch to Testnet
  2. Visit noether.exchange/faucet and claim USDC (up to 1,000/day)
  3. Head to noether.exchange/trade and open your first position

No signup. No KYC. No custody. Just a browser and a wallet.

Building on the API instead? Start at docs.noether.exchange/developers.

(back to top)


Architecture

Noether consists of six Soroban smart contracts on Stellar, a Next.js trading frontend, an autonomous keeper bot, and a Tranche 2 off-chain stack (REST + WS API gateway, Soroban event indexer, TypeScript + Python SDKs).

Noether system architecture: six Soroban contracts on Stellar testnet (router, market, vault, vault factory, referral, Noeracle oracle), an Azure keeper bot and indexer feeding a Fastify API gateway, which serves the Next.js frontend and the TypeScript/Python SDKs

The frontend reads the chain directly (Stellar SDK) for trading and oracle prices, and uses sdk-web wrappers over the API gateway for indexed data (vault marketplace, referral stats, leaderboard). User trades route through the Noether Router, which relays a fresh signed Noeracle price and calls the market in the same transaction (verify-then-trade).

Smart Contracts

Contract LOC / Tests Purpose
Market ~2,800 LOC Core trading engine — isolated + cross-margin positions, advanced orders, liquidation, funding
Vault ~990 LOC LP pool — USDC deposits, NOE LP token, PnL settlement with Market
Noeracle Shim ~200 LOC SEP-40 reader — translates lastprice(Symbol) to Noeracle.get_price_pers, scales to 7 decimals
Noether Router ~230 LOC Atomic verify-then-trade — stores a freshly-signed Noeracle price then opens/closes in one tx
Vault Factory T2 · 37 tests User-created trading vaults — share math, 5% min-holding invariant, leader_trade proxies
Referral T2 · 13 tests On-chain referral system — code registration, record_trade accrual, claim payout
Noether Common Shared types, error codes, fixed-point math (utility crate)

(back to top)


How It Works

Position Lifecycle

Sequence diagram: a trader opens a position, the market reads the oracle price and locks collateral in the vault; on close the market computes PnL plus pending funding, settles with the vault and returns USDC to the trader

Order System

  Order Types
  ├── Market ──────── Opens/closes immediately at current oracle price
  ├── Limit Entry ─── Opens a new position when price reaches trigger
  ├── Stop Loss ───── Closes position to cap losses at trigger price
  ├── Take Profit ─── Closes position to lock in gains (market or limit variant)
  ├── Stop Limit ──── Two-phase: stop price triggers a limit order
  └── Trailing Stop ─ Tracks peak price; closes on reversal (1–50% configurable)

  Time-in-Force
  ├── GTC  ─ Good Till Cancelled (default)
  ├── IOC  ─ Immediate Or Cancel (cancels + refunds if trigger not immediately met)
  └── Post ─ Post-Only (rejected if the trigger would fire immediately)

  Flags
  └── Reduce-Only — Restricts order to reducing an existing position only

Orders are placed on-chain and executed by the keeper bot when trigger conditions are met. If slippage exceeds the order's tolerance at execution time, the order is cancelled and collateral refunded — the transaction does not revert.

Cross-Margin

In cross-margin mode, a single USDC pool acts as collateral across all of a trader's positions. Liquidation is decided at the account level, not per-position.

Equity        = poolBalance + totalCollateral + unrealizedPnL + pendingFunding
Used Margin   = totalCollateral (sum across open cross positions)
Free Margin   = Equity − Used Margin
Margin Ratio  = Equity / MaintenanceMargin × 100%      (liquidation at 100%)

Cross-margin deposits and withdrawals use dedicated entry points (deposit_cross_margin / withdraw_cross_margin), with withdrawals gated on equity remaining above maintenance margin.

Liquidation

A position is liquidatable when its equity falls below the maintenance-margin threshold (default 1% / 100 bps).

Liquidation Price (Long)  = entry − entry × (1/leverage − mm_bps/10000) / PRECISION
Liquidation Price (Short) = entry + entry × (1/leverage − mm_bps/10000) / PRECISION

Keeper Bot (every ~5s):
  ├── Isolated:  get_all_position_ids() → is_liquidatable() → liquidate()
  └── Cross:     attempt liquidate_cross_account() for each tracked cross-trader

Keeper reward = remaining_collateral × liquidation_fee_bps / 10000
                (capped at 10% of collateral)

Funding Rate

funding_rate = base_rate × (longs − shorts) / max(longs, shorts)

Positive rate → longs pay shorts
Negative rate → shorts pay longs

Funding is lazy: the keeper calls apply_funding() hourly, which stores the global rate. Actual funding is calculated and applied per-position on close or liquidation — gas-efficient, no mass-update transaction.

Vault Flow

Diagram of the LP loop: deposit USDC into the vault, receive pre-minted NOE; the market settles trader PnL and fees against the vault; withdrawals return a pro-rata share of AUM
AUM       = total_usdc + accumulated_fees − unrealized_trader_pnl   (floored at 0)
NOE Price = AUM × PRECISION / circulating_NOE

NOE is a SAC-wrapped classic Stellar asset, pre-minted to the vault. Deposits move NOE via transfer (not mint); withdrawals require the user to first approve() the vault.

User-Created Vaults (Tranche 2)

Anyone can deploy a new trading vault via vault_factory.create_vault(leader, name, profit_share_bps). The leader trades on behalf of all depositors using shared collateral and earns a profit share above the high-water mark; depositors hold share tokens denominated in vault NAV.

Sequence diagram: leader creates a vault, depositors receive shares at NAV, the leader trades shared collateral through proxied calls to the market, withdrawals pay pro-rata NAV minus the profit share; a 5 percent leader minimum holding is checked on every withdraw
NAV          = vault_usdc + open_position_equity
Share Price  = NAV × PRECISION / total_shares
Profit Share = leader_share_bps × (NAV − HWM) / 10000      (default: 10%)
Invariant    : leader's own deposit ≥ 5% of total shares   (checked every withdraw)

The 5% min-holding invariant is enforced on every withdraw — leaders cannot drain below it while depositors remain. Browse the marketplace at /vaults.

Referral System (Tranche 2)

The referral contract lets traders mint a short code, share it via ?ref=CODE links, and accrue revenue from referred trades. The whole loop runs on-chain: referees pay 4% less in fees and referrers earn a 10% share of the fee paid by their referees, applied by the market's fee path on every trade.

Sequence diagram: referrer registers a code, referee binds to it, and on every trade the market fee path calls record_trade on the referral contract — 4 percent referee discount, 10 percent of the fee accrues to the referrer, claimable as USDC
discount_bps         = 400    (4%, referee's per-trade fee discount)
referrer_share_bps   = 1_000  (10% of full fee accrues to referrer)
min_code_volume      = 0      (lowered on testnet — anyone can register)

Status (testnet). Live end-to-end since 2026-08: the market's fee path calls record_trade on every fee, so the 4% referee discount, the 10% referrer accrual, and claim() payouts are all active on-chain. The hook shipped through the market's in-place upgrade() path — no redeploy, same addresses.

Browse and claim at /referrals.

Oracle (Noeracle, pull-based + signed)

Data-flow diagram: the Noeracle service signs price rounds off-chain, the keeper publishes attestations to the Noeracle contract, the SEP-40 shim exposes lastprice to the market; the Noether router relays a fresh signed price and trades in the same transaction

For user trades, the noether_router collapses verify + trade into one transaction (open_with_price / close_with_price): it stores a freshly-signed price, then calls the market — so the price is only seconds old at execution and never trips the staleness check. Prices are i128 at 7 decimals.

Keeper Loop

The keeper is an autonomous TypeScript bot that runs continuously, executing four phases per cycle.

Keeper Bot (5-second cycle)
═══════════════════════════

  Phase 1 — Oracle Updates (every 30s)
    Fetches Ed25519-signed attestations from Noeracle (api.noeracle.org)
    Publishes them on-chain via Noeracle.update_ed25519_persistent
    50% price-change circuit breaker

  Phase 2 — Liquidation Scan (every cycle)
    Isolated:  check every open position against maintenance margin → liquidate
    Cross:     attempt liquidate_cross_account per tracked trader

  Phase 3 — Trailing Peaks + Order Execution (every cycle)
    update_trailing_peak() for each TrailingStop order
    execute_order() for any order whose trigger conditions are met
    Slippage exceeded → order cancelled, collateral refunded (reward = 0)

  Phase 4 — Funding Rate (every 1h)
    apply_funding() — stores new global rate for lazy per-position application

Off-Chain Pipeline (Tranche 2)

Tranche 2 introduced a Soroban event indexer feeding a Fastify REST + WebSocket gateway, with TypeScript and Python SDKs on top — see the architecture diagram above:

Stellar Soroban (getEvents) → Indexer (decode & project) → PostgresAPI Gateway (Fastify REST + WS, closed beta) → SDKs / Web

  • Indexer (indexer/) polls getEvents from a persistent ledger cursor, dispatches by contract address (router.ts), runs per-contract decoders, and writes structured projections to Postgres.
  • API Gateway (api/) reads projections, serves REST routes (/v1/markets, /v1/candles, /v1/trades, /v1/positions, /v1/leaderboard, /v1/oracle, /v1/account, /v1/orders, /v1/tx, /v1/vaults, /v1/referral, /v1/events, /v1/keys, …), and broadcasts 4 WebSocket channel families. OpenAPI auto-served at /docs; full reference at docs.noether.exchange/developers. Wallet-challenge auth issues bearer keys hashed at rest with an HMAC pepper.
  • SDKs ship sub-clients matching the API surface 1:1 plus an auto-reconnecting WsClient (noether-sdk on both npm and PyPI).
  • Frontend uses the SDKs for indexed data (vault marketplace, referral stats, leaderboard) and reads the chain directly via @stellar/stellar-sdk for trading + oracle prices.

Closed beta. API-key issuance is gated by an API_KEY_ALLOWLIST while the protocol matures. Wallet-only Soroban operations (registering a referral code, opening positions, depositing to vaults) do not require the gateway — they go straight to chain and work for any wallet. Email or join Discord to request beta access.

(back to top)


Trading Parameters

Parameter Value Notes
Max Leverage 10x 25x planned for mainnet
Min Collateral 10 USDC Prevents dust positions
Maintenance Margin 1% (100 bps) Triggers liquidation
Liquidation Fee 5% (500 bps) Keeper reward, capped at 10% of collateral
Base Maker Fee 0.020% Lowest tier: 0.005%
Base Taker Fee 0.050% Lowest tier: 0.020%
Funding Rate 0.01% / hour base Lazy — applied per-position on close
Price Precision 7 decimals PRECISION = 10_000_000
Fee Precision Deci-bps (100,000) 1 unit = 0.001% — sub-bps accuracy
Max Price Staleness 60 seconds Market rejects older quotes
Max Position Size $100,000 Per position
Supported Markets 14 pairs — BTC, ETH, XLM, SOL, XRP, ADA, BNB, TRX, HYPE, DOGE, ZEC, LINK, BCH, LTC HYPE is API-only for now

Fee Tiers (14-day rolling volume, testnet)

Tier Volume Threshold Maker Taker
0 $0 0.020% 0.050%
1 > $20,000 0.015% 0.040%
2 > $50,000 0.010% 0.030%
3 > $100,000 0.005% 0.020%

Mainnet thresholds will be raised to $1M / $5M / $25M.

(back to top)


Built With

Smart Contracts

Rust Soroban WebAssembly

Rust (Edition 2021) · Soroban SDK 21.0 · Compiled to WASM with opt-level=z, LTO, panic=abort, stripped symbols.

Frontend

Next.js TypeScript TailwindCSS React

Next.js 14 (App Router) · TypeScript 5.2 · Tailwind CSS · Zustand · Framer Motion · Three.js · TradingView lightweight-charts · @stellar/stellar-sdk 14 · @creit-tech/stellar-wallets-kit (Freighter + LOBSTR + WalletConnect) · leaderboard via the gateway (/v1/leaderboard).

Keeper Bot

Node.js TypeScript

Node.js · TypeScript · @stellar/stellar-sdk · publishes Ed25519-signed Noeracle attestations on-chain (~30s cadence) · liquidation scans, order execution, hourly funding.

API Gateway (Tranche 2)

Node.js TypeScript

Fastify · @fastify/swagger (OpenAPI at /docs) · @fastify/websocket · Postgres (Azure) via @noether/db · HMAC-peppered bearer keys · tiered rate limiting · vitest · Dockerised for Azure Container Apps.

Indexer (Tranche 2)

Node.js TypeScript

Soroban getEvents polling · per-contract decoders → Postgres (Azure) projections · persistent ledger cursor · vitest · Dockerised for Azure Container Apps.

SDKs (Tranche 2)

Infrastructure

Azure Container Apps (web, api, indexer, keepers) · Azure Database for PostgreSQL · Stellar Testnet (RPC + Horizon).

(back to top)


Contract Addresses

Current testnet deployment: the Batch-1 stack, deployed 2026-07-21 and upgraded in place since — addresses are stable across code upgrades because the market swaps WASM via upgrade() rather than redeploying. Canonical source is contracts.json. A running gateway echoes the addresses it actually serves at GET /v1/health, and the always-current table lives at docs.noether.exchange/protocol/contracts:

Contract Address
Market CBHHWFAYLB3SXJCE232DC6WNSK74IBEOROAGCI2AFBA2H5NQOH2KYKNN
Vault CBSWA5P75NGV2LP5KOY7A7LOAX2CENI5OYBSJ5IVLHENKQJF2I3ZBSYE
Noether Router (verify-then-trade) CBDVQKYEN6QMRGQZC77DFYEQXQHDMCVJ3TPBJKNERJVMIESA6GQT44LG
Noeracle Shim CDRQJDCZ2EKIVAM6D6U2YFTE7VNMN3TFUUJGZ5SKAFB5TCLMSHSSWU6N
Noeracle (signed price source) CBTO5K2NLG2KYHQDL5ME4SWFQ5GRR7GVU4DFATOXGVS3OUJJDFF2YYNS
Vault Factory (T2) CAG5E6IM32GFEXGZOXWLFHNVRMDOYGPRZKZSBFXXHVJ5Q5MNJUSNQKT7
Referral (T2) CB4A2OHP6BKKF2RC532PPRE7K4X3UOZEVASEQTTTWMRSZGUN2AV2REND
USDC Token CA63EPM4EEXUVUANF6FQUJEJ37RWRYIXCARWFXYUMPP7RLZWFNLTVNR4
NOE Token CADEAZ3TT5SIGJVBIWMMWC4TFZKPKGPGGJ6O4JGAAZTLR6MIBDRBQ4H5
Admin GCKIUOTK3NWD33ONH7TQERCSLECXLWQMA377HSJR4E2MV7KPQFAQLOLN

NOE asset: code NOE, issuer = Admin address. Addresses rotate on testnet resets and redeploys — trust contracts.json / /v1/health over any snapshot.

Prices come from Noeracle, a pull-based, Ed25519-signed price oracle (~500ms rounds). The keeper publishes signed attestations on-chain; the market reads them via the noeracle_shim (a SEP-40 reader translating to Noeracle.get_price_pers).

Network Configuration

Network:    testnet
RPC URL:    https://soroban-testnet.stellar.org
Horizon:    https://horizon-testnet.stellar.org
Passphrase: Test SDF Network ; September 2015

(back to top)


Project Structure

noether/
├── contracts/              # Soroban smart contracts (Rust)
│   ├── market/             # Trading engine (positions, orders, liquidation)
│   ├── vault/              # LP pool + NOE token
│   ├── noeracle_shim/      # SEP-40 reader → Noeracle.get_price_pers
│   ├── noether_router/     # Atomic verify-then-trade (Noeracle)
│   ├── vault_factory/      # T2 — user-created trading vaults
│   ├── referral/           # T2 — on-chain referral system
│   └── noether_common/     # Shared types, errors, fixed-point math
├── web/                    # Next.js 14 frontend
│   ├── app/                # Pages: trade, portfolio, vault, leaderboard, faucet
│   ├── components/         # React components (trading, vault, wallet, landing, ui)
│   └── lib/
│       ├── stellar/        # Contract interaction layer (never called from components)
│       ├── store/          # Zustand stores (walletStore, tradeStore)
│       ├── hooks/          # useWallet, usePriceData, useFaucet
│       └── utils/          # constants, formatting
├── scripts/
│   ├── keeper/             # Autonomous keeper bot (TypeScript)
│   ├── build_contracts.sh  # Compile + optimize all WASM
│   ├── deploy_staging.sh   # Blue-green testnet deploy → verify → promote
│   ├── deploy_production.sh# Production stack deploy
│   ├── fund_market.sh      # Transfer USDC to market (interactive)
│   └── legacy/             # Retired one-shot deploy scripts (exit-guarded)
├── packages/               # Tranche 2 — shared monorepo packages
│   ├── types/              # @noether/types  · domain types (Position, Order, …)
│   ├── shared/             # @noether/shared · precision, contracts loader, network
│   └── tx-builders/        # @noether/tx-builders · Soroban tx assembly (api + sdk-ts)
├── api/                    # Tranche 2 — REST + WebSocket gateway (Fastify)
├── indexer/                # Tranche 2 — Soroban event indexer (Postgres)
├── sdk-ts/                 # Tranche 2 — public TypeScript SDK (npm)
├── sdk-py/                 # Tranche 2 — public Python SDK (PyPI)
├── docs/                   # README assets + GIT_WORKFLOW.md, CONTRIBUTING.md
├── .github/                # PR template, CI workflows
├── .husky/                 # Branch + commit-msg hooks
├── package.json            # npm workspace root (api, indexer, sdk-ts, packages/*)
├── tsconfig.base.json      # Shared TypeScript config
├── contracts.json          # Authoritative deployed addresses
├── LICENSE                 # MIT
└── .env.example            # Environment template

Monorepo note. The web/ and scripts/keeper/ packages keep their own package.json and install paths — they are not workspace members for now. Only the new Tranche 2 packages (api/, indexer/, sdk-ts/, packages/*) are wired into the root npm workspace. See docs/GIT_WORKFLOW.md for the branch model and docs/CONTRIBUTING.md for setup instructions.

Pages

Page Path Description
Landing / Protocol overview with live trading preview
Trade /trade Full trading interface — chart, order panel, positions, trade history
Portfolio /portfolio Open positions, trade history, PnL tracking
Protocol Vault /vault LP interface — deposit USDC, withdraw NOE, pool stats
Vaults Marketplace /vaults T2 — browse user-created trading vaults
Vault Detail /vaults/[id] T2 — deposit / withdraw a single vault
Vault Manage /vaults/[id]/manage T2 — leader panel (trade + claim fees)
Referrals /referrals T2 — register a code, share, claim accrued rewards
API Keys /api-keys T2 — in-browser issuance of gateway bearer keys (closed beta)
Leaderboard /leaderboard Top traders by volume and PnL (proxied from the gateway /v1/leaderboard)
Faucet /faucet Testnet USDC (up to 1,000/day)

(back to top)


Getting Started

Prerequisites

Run the Frontend

git clone https://github.com/NoetherDEX/noether.git
cd noether/web
npm install
npm run dev

Open http://localhost:3000.

Run the Keeper Bot

cd scripts/keeper
npm install
cp ../../.env.example .env    # Configure your keeper keypair
npm start                     # or: npm run dev (auto-restart)

Run the API + Indexer (Tranche 2 — monorepo)

# From repo root — npm workspaces (api, indexer, sdk-ts, packages/*)
npm install
npm run build:packages         # types → shared → tx-builders (order matters)

# Indexer — polls Soroban events into Postgres
npm -w @noether/indexer run migrate
npm -w @noether/indexer run dev

# API gateway — Fastify REST + WS, port 4000
npm -w @noether/api run dev
# OpenAPI / Swagger UI: http://localhost:4000/docs

# All tests across workspaces
npm test

Closed beta. Bearer-key issuance via the gateway honours API_KEY_ALLOWLIST. Wallet-only Soroban calls (registering a referral code, opening positions, depositing to vaults) work without an API key. See Security.

Build & Deploy Contracts

# Build all contracts (optimized WASM)
./scripts/build_contracts.sh

# Blue-green testnet deploy → verify → promote
./scripts/deploy_staging.sh

# Production stack deploy
./scripts/deploy_production.sh

# Oracle-side contracts
./scripts/deploy_noeracle_shim.sh
./scripts/deploy_noether_router.sh

# Tranche 2 contracts
npx tsx web/scripts/referral-set-min-volume.ts      # set on-chain min_code_volume

One-shot deploy and repair scripts from earlier stack generations were removed once their work shipped — git history keeps them if archaeology is ever needed.

Addresses are written to contracts.json automatically. Update .env and the Azure container app env vars (web, api, indexer, keepers) manually so they match.

Environment Variables

Copy .env.example to .env and populate:

# Network
NETWORK_PASSPHRASE="Test SDF Network ; September 2015"
SOROBAN_RPC_URL="https://soroban-testnet.stellar.org"
# SOROBAN_RPC_URLS="https://primary,https://fallback"   # comma-separated failover

# Keys
ADMIN_SECRET_KEY=S...           # Deployment + admin operations
KEEPER_SECRET_KEY=S...          # (Optional) dedicated keeper key
ORACLE_SECRET_KEY=S...          # (Optional) dedicated oracle-updater key

# Contract addresses (canonical source: contracts.json)
NEXT_PUBLIC_MARKET_ID=C...
NEXT_PUBLIC_VAULT_ID=C...
NEXT_PUBLIC_NOERACLE_SHIM_ID=C...
NEXT_PUBLIC_NOERACLE_ID=C...
NEXT_PUBLIC_NOETHER_ROUTER_ID=C...
NEXT_PUBLIC_NOERACLE_API_URL=https://api.noeracle.org
NEXT_PUBLIC_VAULT_FACTORY_ID=C...    # Tranche 2
NEXT_PUBLIC_REFERRAL_ID=C...         # Tranche 2
NEXT_PUBLIC_USDC_TOKEN_ID=C...
NEXT_PUBLIC_NOE_TOKEN_ID=C...

# Frontend
NEXT_PUBLIC_NOETHER_API_URL=http://localhost:4000   # api gateway base URL
FAUCET_ADMIN_SECRET_KEY=S...                        # /faucet payments

# Indexer (Tranche 2)
DATABASE_URL="postgresql://postgres:dev@localhost:5432/postgres"  # managed Postgres URL in prod (Azure)
INDEXER_POLL_INTERVAL_MS=2000

# API Gateway (Tranche 2)
API_PORT=4000
API_HMAC_PEPPER=                      # openssl rand -hex 32 — must be stable across restarts
API_CORS_ORIGIN=*
API_KEY_ALLOWLIST=                    # comma-separated G… addresses for closed beta

The keeper's secret-key resolution order is KEEPER_SECRET_KEYORACLE_SECRET_KEYADMIN_SECRET_KEY. Using a dedicated oracle wallet avoids sequence-number conflicts with the admin wallet during deploys.

(back to top)


Roadmap

Noether is being delivered in three tranches under Stellar Community Fund #41.

Tranche 1 — Trading Engine Upgrades · $17,240 · Complete

  • Cross-margin mode (shared collateral, per-trader equity, account-level liquidation)
  • Advanced orders: Stop-Limit, Take-Limit, Trailing Stop, Reduce-Only
  • Time-in-force: GTC, IOC, Post-Only
  • Maker/taker fee system with 4 volume-based tiers

Tranche 2 — Developer Tooling & Vault Ecosystem · $25,800 · Code Complete · Operator steps pending

  • Public REST + WebSocket APIs (api/ — Fastify, OpenAPI at /docs, 4 WS channel families, 37 vitest tests)
  • TypeScript SDK — noether-sdk with WsClient (25 tests)
  • Python SDK — noether-sdk mirroring the TS surface (12 tests)
  • User-created trading vaults — vault_factory contract (37 tests) + /vaults marketplace + leader manage panel
  • Multi-wallet support — Freighter, LOBSTR, xBull, Albedo, Ledger via Stellar Wallets Kit
  • On-chain referral system — referral contract (13 tests) + sticky ?ref=CODE banner + /referrals dashboard
  • Soroban event indexer — Postgres projections (Azure Database for PostgreSQL) feeding the API gateway

Pending operator steps:

  • On-chain referral discount hook — live on both markets since 2026-08, shipped through the market's in-place upgrade() path (see Referral System)
  • npm publish — noether-sdk live on npm
  • PyPI publish — noether-sdk live on PyPI
  • Paid Soroban RPC endpoint (SOROBAN_RPC_URLS) for keeper + indexer — see docs/RPC.md

Tranche 3 — Mainnet Launch · $34,480 · In Progress

  • Production oracle hardening — Noeracle multi-publisher (M-of-N) signatures + TWAP for funding/liquidation
  • All contracts deployed to Stellar mainnet with 25x leverage
  • Partial liquidation (20% initial, 30s grace period) + insurance fund
  • 10+ trading pairs — 14 live on testnet; mainnet deploy pending
  • Mobile-responsive UI
  • Comprehensive documentation — live at docs.noether.exchange

(back to top)


Security

  • Authorization — Every state-changing function calls require_auth() on the relevant signer (trader for trading, admin for admin ops)
  • Leverage cap — Hard-coded 10x limit mitigates protocol risk during the testnet phase
  • Collateral floor — 10 USDC minimum prevents dust positions
  • Oracle validation — Noeracle Ed25519-signed prices verified on-chain; market enforces a 60s staleness check (the router relays a fresh price in the same transaction, so execution-time prices are at most seconds old)
  • Integer math only — No floating point anywhere; all values are 7-decimal fixed-point i128
  • Overflow protectionoverflow-checks = true in the release profile
  • Emergency withdraw — Admin-only withdrawal gated on paused state (vault)
  • API gateway in closed beta — Bearer-key issuance is restricted to API_KEY_ALLOWLIST while the protocol matures. Wallet-only Soroban calls always work without a key
  • Referral economics on-chain — The market's fee path calls referral.record_trade on every fee; the 4% referee discount and 10% referrer accrual are enforced by the contracts, not by any off-chain service
  • Responsible disclosure — see SECURITY.md; report vulnerabilities privately to security@noether.exchange rather than filing a public issue

Testnet only. Unaudited. Use at your own risk. Contracts are deployed on Stellar Testnet and have not undergone a formal audit. Do not use with mainnet funds.

(back to top)


License

Distributed under the MIT License. See LICENSE for the full text.

(back to top)


Team

Role
Yahya Emir Soyer Co-founder & CEO — Smart Contracts (Soroban/Rust) https://github.com/y4hyya
Mert Cicekci Co-founder & CTO — Full-stack Web3, DevRel https://github.com/merth

Contact & Community

(back to top)


Acknowledgments

(back to top)


Why "Noether"?

The protocol is named after Emmy Noether (1882–1935), one of the most important mathematicians of the 20th century. Her namesake theorem — Noether's theorem — proves that every continuous symmetry of a physical system corresponds to a conservation law. Symmetry under time translation gives conservation of energy; symmetry under spatial translation gives conservation of momentum. It is, quietly, one of the most consequential results in modern science.

We chose the name because we believe the same principle belongs in financial infrastructure: invariants should be structural, not ceremonial. In Noether, the conservation law is simple — for every long there is a short, for every profit a loss, for every deposit a claim. The protocol enforces these symmetries on-chain, where no operator, exchange, or intermediary can bend them.

Einstein called her "the most significant creative mathematical genius thus far produced since the higher education of women began." Noether was paid nothing for her first seven years of university teaching, was barred from a professorship in Göttingen for being a woman, fled Nazi Germany in 1933, and died two years later in the United States. Her work underpins modern physics, algebra, and topology — and, we hope, a small contribution to open financial systems.

(back to top)


Built with Rust, Soroban, and mathematics on Stellar.

About

This is our core repository, which contains the entire project structure, including contracts, scripts, and the UI.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages