For builders

Build on private markets.

A read API with no keys and no per-client state, a relayer that submits proofs for you, and a small SDK that keeps keys in the user's browser.

Read API

Public data

Base URL https://api.yourdomain.xyz. No keys. Responses are JSON.

GET/v1/syncLatest indexed block and note-tree root.
GET/v1/deploymentChain ID and every contract address.
GET/v1/recordsEncrypted notes since a cursor. Only your keys can read yours.
GET/v1/tree/path/:indexMerkle path for a note, used when proving.
POST/v1/nullifiersCheck which notes are already spent.
GET/v1/spot/poolsEvery pool with reserves and fee.
POST/v1/spot/quoteQuote a swap: amount out, impact, fee.
GET/v1/marketsMarkets with price, max leverage and status.
GET/v1/markets/:id/fundingHourly funding history for a market.
Relayer

Submit proofs

The relayer submits a user's proof and pays the gas, so the user's public wallet never touches the trade.

POST/v1/relay/:actionSubmit a proof. Actions: swap, perp-open, perp-close, lp-add, lp-remove, maker-post.
GET/v1/jobs/:idJob state: queued, proving, submitted, confirmed, refunded.
GET/v1/relayerRelayer address, fee and queue length.
SDK

Keys stay client-side

npm i @uponly/private-sdk

import { deriveKeys, addressOf, scanCreated } from "@uponly/private-sdk";

// 1. One wallet signature makes the keys. Nothing leaves the browser.
const sig  = await wallet.signMessage(CREATE_ACCOUNT_MESSAGE);
const keys = deriveKeys(sig);

// 2. Your private receiving address
const addr = addressOf(keys);

// 3. Find the notes that belong to you
const notes = await scanCreated(keys, { api: "https://api.yourdomain.xyz" });

Package and API names are placeholders until you publish them. The app in this repo runs the same flows on a built-in testnet simulator (assets/engine.js).

Try it

Live response

Sample GET /v1/markets built from the test oracle in your browser: