Learn · how this exchange actually works

What it takes to place one real order.

This page is written from a live seller and buyer run on this exchange, not from the documentation’s description of it. Every number below is measured, not estimated. It covers the whole stack — what DEX.DO ships and where each of its front doors leads, and what this client can do for you without a terminal.

This is Acki Nacki mainnet, with real funds. There is no faucet and no test mode. Every command below moves real SHELL, and a failed attempt still spends gas.
01 · The unit

Inference, sold by the tick

What trades here is not a token and not a subscription — it is inference capacity, sold by the tick. 1 tick = exactly 1,000,000 model tokens. DEX.DO devs, 2026-09-03: “One tick is a billing and capacity unit equal to exactly 1,000,000 model tokens. Orders contain a whole number of ticks, while delivery accounting counts the actual model tokens produced.”

An ask at 1.00 SHELL/tick is 1.00 SHELL per million tokens. Orders on the book always carry a whole number of ticks — you cannot place an order for half a tick — but what you are actually billed for, once a deal is running, is the real token count the model produced. Those two things can differ: the worked settlement in §9 is a buyer who reserved 4 ticks and was billed for 1,002,100 tokens.

This definition is not in the OpenAPI, read-api.md, airegistry-inference.md, or the CLI README — it came from asking the people who built it.

02 · Where things live

One market, several front doors

DEX.DO is the market. This site is a client onto it, and not the official one — so before anything else, here is the whole stack and what each door actually does. Every one of them reads the same Acki Nacki mainnet; there is no private database behind any of it, on their side or ours.

dex.do
The product’s own front page — model catalogue, desktop installers, and the NACKL launch programme. The order book shown there is a demonstration; the prices and the depth on it are not what is resting on chain. §7 is.
get.dex.do/install.sh
Redirects to the latest dexdo-cli release on GitHub. This is the installer step 1 of §5 runs.
app.dex.do
The official web app. What it serves today is the referral programme.
seasons.dex.do
Season 2. Connect a wallet, earn points for trading and for really consuming what you bought, claim NACKL at the end. The weights are deliberately private; real consumption is stated as the highest earner.
indexer.dex.do
The public read API. Every market, book, fill and figure on this site comes from it.
dex.acki.pro
This site. An independent read-and-trade client: it holds no funds, keeps no account of yours, and never sees your note key — the key is encrypted in your own browser and nowhere else.

The line that matters to anyone standing at the trade screen is not which domain — it is which of these still needs a terminal.

In this browser
  • Read every market, book and fill — no wallet, no account, no sign-up.
  • Hold one or more note keys, encrypted, in this browser alone.
  • Place a buy — rest it on the book, or fill it now against a resting ask.
  • Cancel one of your orders, or all of them.
  • Watch your own orders and your note balance.
Only the dexdo CLI
  • Mint a note — it needs a zero-knowledge proof no browser can produce.
  • Bind and fund the Hot wallet that deploys it.
  • Sell anything — see §6.
  • Consume the inference you bought — see §5, step 6.
  • Reclaim escrow from a fill that nothing was attached to.

The split is not arbitrary, and the right-hand column is not a to-do list. Everything on the left is one signed message to your own note, which a page can build and post. Everything on the right needs either a proof a browser cannot make, or a process that keeps running — the gateway that serves a model for as long as its offer stands, the runtime that receives a stream. A tab you can close is neither.

A fill is not a delivery. An order placed here that fills with no buyer runtime attached leaves escrow that has to be reclaimed. Placing is the easy half — §5 step 6 is the half that actually gets you tokens.

One thing this site cannot show you is your Season standing: no public endpoint exposes points or rank, so that figure lives on seasons.dex.do and nowhere else. Expect it to read near zero while your funds are still sitting in a note — points stay pending until you withdraw note → wallet, and the withdrawal releases the whole season at once. One Season 1 entry went from 150 points to 1,080 the moment its notes were withdrawn: 137 fills had scored all along and were simply invisible.

03 · Accounts

Three layers, one order

Placing an order does not happen from “your wallet” in the way most exchanges mean it. There are three separate accounts between you and a fill, and the tool you run can only reach one of them directly.

Acki Nacki wallet

The multifactor wallet app on your own device. Two factors, no seed phrase. This is what you install and what holds your keys.

Hot wallet

The only wallet the dexdo CLI can operate. You fund this one directly — it is what “350 SHELL in the Hot wallet” in §4 refers to.

PrivateNote

The actual on-chain buyer or seller. Anonymous, and it is the account that holds the SHELL that pays for inference — deployed with note deploy. It is also what signs when you place an order from this page: unlocking a note here gives the browser that one key, and nothing above it.

The practical consequence: funding your Hot wallet is not the same as funding your trading account. The Hot wallet is a relay you fund so the CLI can deploy and top up a note; the note is what actually places, holds, and settles the order.

04 · Costs

What it costs, and where each charge goes

dexdo note deploy --nominal N100 needs 350 SHELL in the Hot wallet, not 100. RootPN.generateVoucher subtracts a 250 SHELL GAS_DEPOSIT before matching the remainder against the allowed nominals. The 250 is not lost — it lands in the note as its own gas pocket. Fund 100 and the deploy simply fails.

note deploy --nominal N100
350 SHELL
250 SHELL GAS_DEPOSIT withheld into the note’s own gas pocket; the remainder is matched against N100.
BUY placement
0.025 SHELL
Burned at placement — PrivateNote.placeInferenceBuy, contracts 4.0.36.
Maker fill
−0.02
Rebate to the resting order, from the live market payload.
Taker fill
0.025
Fee on the order that crosses, from the live market payload.
Failed onboarding attempt
~3 SHELL
Gas spent even though nothing was produced — retry, it does not get cheaper to wait.
05 · Buying

Buying, end to end

Four steps get you an account that can trade, a fifth places the order, and a sixth is where you actually use what you bought. Steps 1–4 happen once and are CLI-only. Step 5 you can do on this page or from the CLI — both write the same call to the same contract. Step 6 is the CLI again, and there is no way round it.

1Install the CLI
curl -fsSL https://get.dex.do/install.sh | sh

Needed even if you intend to trade from this page. Minting a note and binding a wallet are CLI-only — §2 — and the CLI is the only thing that can consume what you buy.

2Bind your wallet
dexdo wallet onboard gosh-ai --data-dir ~/dexdo

Done once. A failed attempt here still costs ~3 SHELL of gas — see §4.

3Deploy your note
dexdo note deploy --data-dir ~/dexdo --nominal N100

Needs 350 SHELL in the Hot wallet — see §4 for why.

4Write the failure policy
dexdo policy init --data-dir ~/dexdo

dexdo buyer and dexdo seller both fail closed on startup if this is missing or incomplete — skip it and the next step refuses to run. It records what should happen when a counterparty vanishes mid-deal, which only you can decide.

5Place the buy

One call, two places to make it from. The order is PrivateNote.placeInferenceBuy, signed with your note’s own key and posted to the chain’s message endpoint. There is no DEX.DO write API in the middle of it, which is exactly why a page can do this at all: it is your note that signs, not a server.

From this page, no terminal
  1. Set up the note. The note strip on the trade and wallet screens reads Set up the first time. Give it the pn_pool.json that step 3 wrote and a passphrase of your choosing. The key is encrypted in this browser with that passphrase and never leaves it; the passphrase is never stored anywhere.
  2. Unlock it when you want to trade. The session locks itself after 10 minutes and whenever you hide the tab, so a walked-away laptop cannot sign.
  3. Set ticks and a ceiling on the buy form — the same two numbers as the command below, and the same rules: minimum 2 ticks, and a price in whole SHELL.
  4. Choose how it should behave. Rest on the book sits for an hour and can be cancelled from this page. Fill now, or drop takes all of it from one seller immediately or does nothing at all — the same all-or-nothing shape dexdo buyer sends.
  5. Cancel from your own orders, one at a time or all at once. A cancel built and signed in a browser executed on mainnet on 5 Sep 2026; nothing about this path is theoretical.

What you commit when you press it: the contract holds ticks × (your ceiling + the market’s taker commission, 2.5%) out of your note’s SHELL balance — the form shows the exact figure before you sign — and placement itself burns 0.025 SHELL (§4). Cancel a resting order and the escrow comes back. A filled one does not — it has become a deal waiting for step 6.

Or place the same order from the terminal — useful when you are about to run step 6 in it anyway:

dexdo buyer --data-dir ~/dexdo \
  --frame-model <model-ref-name> \
  --ticks <n> \
  --max-price-per-tick <whole SHELL> \
  --local-listen 127.0.0.1:8787 \
  --continuity-mode on-demand \
  --wait-for-seller
--frame-modelWhich model this order trades.
--ticksTicks to buy. Minimum 2 — a 1-tick buy does not serve local streaming.
--max-price-per-tickA ceiling, in whole SHELL — 3 means three SHELL a tick. The CLI rejects a decimal, so the 1.00 SHELL price this page displays as 1.00.000 goes on the command line as 1.00. You do not overpay by setting it higher — the book fills at the ask.
--local-listen 127.0.0.1:8787Opens the local endpoint you call in step 6 to actually consume what you bought.
--allow-unverified-model — NOT above, and that is deliberateThis flag is how you pay for mock strings. Without verification data the buyer fails closed, which is correct: it will not spend on a model it cannot check. This flag makes it run anyway. It waives only the reference-availability preflight — the other checks still run when their data is there — but with no models.json for the model there is no data, so nothing checks what you are streamed. On 7 Sep 2026 that content check is what caught a seller on this exchange returning fake replies: model identity verification failed (content check). Give the buyer a --models file instead, and reach for this flag only when you have decided the risk is yours to take.
--continuity-mode on-demandSet this deliberately. The CLI defaults to proactive, which keeps a warm next deal ready and may pre-buy while idle — spending SHELL with no requests running. on-demand buys only after real traffic; the first request after an idle stretch waits for a fresh deal.
--wait-for-sellerMatters because books are usually empty — see §7. Without it, an empty book fails the order instead of waiting for an ask to appear.
6Consume it
curl http://127.0.0.1:8787/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"messages":[{"role":"user","content":"hello"}]}'

This step does not happen in the browser. The CLI serves an OpenAI-compatible endpoint on your own machine, streaming from the seller’s gateway over an encrypted channel. Point any OpenAI-compatible client at http://127.0.0.1:8787/v1/chat/completions — this page cannot do it for you.

06 · Selling

Selling, end to end

Selling cannot be done from this page, and that is not a gap waiting to be closed. Posting an ask needs a deal already on chain and a gateway process serving your model for as long as the offer can be taken — for the hour it rests, and then for the whole stream if someone takes it. A browser tab is not a server. The Sell tab on the trade screen hands you the exact command for the numbers you typed instead of pretending otherwise.

The shape is provision → seller → gateway: register capacity and post a bond, post the ask and wait, then serve the gateway your buyer’s CLI connects to. Steps 1–3 (install, onboard, note deploy) are identical to buying — see §5.

4Provision
dexdo provision --data-dir ~/dexdo \
  --frame-model <model-ref-name> \
  --note-key <your-note.key> \
  --price-per-tick <whole SHELL> \
  --max-ticks <n> \
  --output ~/dexdo/market.json

Registers your capacity to sell inference for this model and posts the seller’s bond — 2 ticks’ worth, 2 SHELL at the current 1.00 SHELL price floor. The bond returns in full on a clean close; only a dispute that runs to timeout with no concession burns it — see §9.

5Post the ask
dexdo seller --data-dir ~/dexdo \
  --market ~/dexdo/market.json \
  --note-key <your-note.key> \
  --price-per-tick <whole SHELL> \
  --gateway-listen 0.0.0.0:8443 \
  --gateway-advertise <your-public-host>:8443

An offer rests for about an hour and then expires if nobody takes it. Roughly half of the offers observed so far expired unfilled — sitting unfilled for a while is the normal state of this book, not a sign anything is wrong.

Every flag on this page was checked against dexdo 0.2.0 --help on 2026-09-04 — top-level, buyer, seller, provision, note deploy, wallet onboard and policy. That check corrected three things this page previously got wrong: the price flags take whole SHELL, the buyer refuses to start without a policy file, and the seller sequence named three flags that do not exist. Flags do change between releases — if your CLI reports a different version, re-run those --help commands before relying on a line here.
07 · Reading the book

How to read this exchange

Most books are empty most of the time — not because nothing is happening, but because an offer’s clock runs out: it rests for about an hour and then expires, and roughly half of the offers seen so far expired unfilled. An empty book is the normal state here, not a signal of a dead market.

Every trade in existence on mainnet has landed at exactly 1.00 SHELL per tick. That is PRICE_STEP, the contract’s floor, enforced as whole-SHELL pricing. There is no price discovery yet — no bid has ever been observed resting on any mainnet book, so the number you see is a floor, not a market-clearing price.

A row on this exchange’s markets table can be in exactly one of three states, and they are three different facts, not shades of the same thing:

A resting ask. The book was read, and there is SHELL-priced capacity for sale right now.

A book we read that was empty. The read succeeded; there is simply nothing offered at this moment.

A book we could not read. The request failed. This must never be shown as empty — an unreadable book tells you nothing about whether it is empty.

Reading the books…
08 · Errors

What goes wrong, and what the error means

SymptomMeaning
Wallet connect fails with “message queue”Transient. Retrying works; one operator needed ~30 attempts. Each on-chain attempt costs gas.
-1102 Mandatory parameter was not sentWrong query-param name. The depth endpoint accepts only inferenceOrderBookAddress.
dexdo market-data list → missing field model at line 1 column 465CLI v0.2.0 expects model; the indexer returns modelRefName (renamed 2026-08-26). Raw HTTP works.
no matchable ask for max_price_per_tick NEither the book is empty, or a stale non-executable head order is blocking the ones behind it. --token-contract <addr> targets a specific ask directly.
QUEUE_OVERFLOW / -1000Chain busy. Retryable.
Seller exits with an error right after a successful saleKnown false failure. getState() is called while reconciling claimTokens(...), after after_deal_done: retire already destroyed the TokenContract, and getState() on a self-destructed account returns nothing. Read dexdo status and settlement-receipt, never the seller’s exit status, to learn whether a deal paid.
Commands that tell the truth
dexdo settlement-receipt <tc> --json --require-conservedExits 0 only when conservation is proven — the check behind §9’s worked example.
dexdo statusThe other source to trust over a process’s own exit code.
dexdo note sweep --to <address>Recovers ECC[2] that lands on a note after its trading balance was withdrawn.
dexdo withdraw-shell --token-contract <TC> --note-addr <addr> --note-key <your-note.key>Collects earnings even when a deal reads as “never opened.”
09 · Settlement

What happens after a match

The deal is a TokenContract escrow holding the buyer’s SHELL, settling tick by tick: open → advance → stop / dispute / reclaim. Both sides post a bond — 2 SHELL each at the current price floor; the seller’s is documented as a 2P bond, 2 ticks’ worth. A clean close, a concession, an abandon, or a seller no-show returns the bond in full. A dispute that reaches timeout with no concession burns the disputed deposit and an equal amount of the seller’s bond.

Worked example — 2026-09-03 08:41 UTC

The first mainnet sale, every leg reconciled.

A buyer took a resting ask about 40 minutes after it was posted. The public trade feed recorded price 1.000000000, qty 4, quoteQty 4.000000000 — that is the API’s full nine-decimal precision for the same 1.00 SHELL floor this page shows elsewhere; prices are stored at nine decimals and displayed at three. Four ticks, bought at the floor.

Delivered
1,002,100
tokens (~1.0021 of the 4 ticks bought)
Terminal state
StreamStopped
To seller
3.0004 SHELL
2.0 bond returned + 1.0004 earned
Refund to buyer
4.075 SHELL

The buyer reserved 4 ticks, was billed for 1,002,100 tokens actually produced, stopped the stream there, and got the rest back. Conservation, checked leg by leg:

In
escrow4.1
buyer bond2.0
seller bond2.0
total8.1
Out
payout7.0754
write-off1.0246
total8.1
unexplained0

You pay for what you actually consume, not for what you reserved. Both sides post a bond, and both bonds come back on a clean close — the seller’s payout above is exactly its 2.0 SHELL bond returned plus 1.0004 SHELL earned; nothing about the buyer stopping early touched it.

Whole exercise, from the seller’s side: 350 SHELL in to deploy the note, 1 SHELL spent provisioning, 1.0004 SHELL earned on this trade.