# Ember testnet — for agents and developers

Three executable paths into the public testnet: **consume inference**, **run an executor node**, **audit**. All parameters below come from the published network snapshot (https://emberinfer.org/network.json), chain `ember-s23-staging`.

> Before you start: this is a public testnet. Testnet Spark is valueless test credit — not money, not sold, not redeemable. All validators are run by a single operator and there is no third-party security audit. Privacy is Phase 0: executing nodes and assigned auditors can see plaintext. Do not send sensitive data.

Machine-readable resources:

- Index: https://emberinfer.org/llms.txt
- OpenAPI 3.1 (chain id and snapshot height embedded): https://emberinfer.org/openapi.yaml
- Network snapshot: https://emberinfer.org/network.json
- MCP endpoint: `https://relay.emberinfer.org/mcp`
- Repository: https://github.com/emberinfer/Ember (Quickstart: https://github.com/emberinfer/Ember/blob/master/docs/QUICKSTART.md)

## Path 1 — Consume inference

### 1a. MCP tools (fastest, no install)

Remote MCP server at `https://relay.emberinfer.org/mcp` (JSON-RPC over HTTPS), same backend and address-based auth as the website.

| Tool | Auth | What it does |
| --- | --- | --- |
| `network_status` | none | Live chain status: height, role counts, profiles and availability. |
| `faucet_claim` | none | Claim faucet test Spark to an address passed as an argument (per-address and per-source daily limits). |
| `get_balance` | none | On-chain balance/stake/nonce for an address. |
| `inference` | signed | One chat completion on the network; settles from your website credit. Returns the text and the request id. |
| `get_trace` | none | The six-segment on-chain trace for a request id. |

Identity is an Ed25519 key you generate; your address is `hex(sha256(public_key))`. The `inference` tool takes `address`, `pubkey` and `signature` (base64) inside its arguments and verifies a signature over the plain string `ember-web/mcp-inference/v1\n<address>\n<model>\n<sha256hex(canonical messages JSON)>\n<max_tokens>`. Canonical messages JSON = compact separators, sorted keys, UTF-8 with non-ASCII unescaped — in Python: `json.dumps(messages, separators=(",", ":"), sort_keys=True, ensure_ascii=False)`.

**Funding inference:** `inference` spends *website credit*, the same prepaid balance the chat page uses. Get test Spark with `faucet_claim`, then transfer some to the website account `d34487a050b0deb094ca4f4e3834b8416212e55a6ffa18bd4eafcd3ca8c7ba3a` with a self-signed chain transfer (see 1d) broadcast through the public RPC — the backend credits your address automatically when the transfer finalizes. Unused credit can be withdrawn through a website session (see openapi.yaml).

Building a product on Ember inference? Partnerships and coordination: emberinfer@proton.me.

**Sizing requests:** the on-chain freeze bound grows with input tokens and `max_tokens`, and the chain rejects a freeze whose bound exceeds the assigned executor's remaining stake exposure (`stake exposure limit`, surfaced by gateways as HTTP 402). On the current testnet, keep `max_tokens` at 64 or below and inputs short; if you still hit it, retry (assignment is per-request) or shorten the request.

### 1b. Website chat (humans)

https://emberinfer.org/chat — browser-local key, faucet, prepaid credit, streamed answers with traces. Read https://emberinfer.org/guide first; it states plainly what the page is and is not (a showcase, not an agent).

### 1c. Your own gateway (spend directly from your account)

The public gateway settles from a single operator consumer account — that is why the website and MCP use prepaid credit. To spend from your *own* account, run your own gateway from the same release: install with `--role gateway`, configure from the template `config/gateway.env.example` (README, "Use it / Call a gateway"), register your consumer account in its auth file, then:

```sh
curl -fsS "$EMBER_GATEWAY_URL/v1/chat/completions" \
  -H "Authorization: Bearer $EMBER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"model":"ember-qwen2.5-1.5b-s22-cpu-v1","messages":[{"role":"user","content":"Say OK"}],"max_tokens":16}'
```

The gateway freezes from your account, the scheduler assigns a node, and settlement lands on-chain under your address. Point the gateway at the public seed and RPC from the table in Path 2.

### 1d. Raw chain operations

The ledger is a CometBFT application. Reads need no auth: `GET http://relay.emberinfer.org:39657/abci_query?path="/state"`, `/account/<address>`, `/hold/<request_id>` (values are base64 JSON). Faucet, direct:

```sh
curl -fsS http://relay.emberinfer.org:39095/testnet/faucet -H 'Content-Type: application/json' \
  -d '{"account":"<your-address-hex>"}'
```

Transfers are JSON envelopes signed with Ed25519 over `ember/chain-tx/v1\x00` + the envelope JSON with `signature: null`, broadcast via `broadcast_tx_commit` on the same RPC. The exact byte format, the session login used by the website API, and every backend endpoint are specified in https://emberinfer.org/openapi.yaml.

## Path 2 — Run an executor node

Nodes connect outbound to the seed — no inbound public port is needed. Serving is paid from the executor share of settled fees (**80%** executor / 15% auditor / 5% consumer refund, with scarcity multipliers up to 2× when coverage is below target; see https://github.com/emberinfer/Ember/blob/master/docs/PRICING.md). Registration stakes the on-chain minimum. Commands follow the project Quickstart; verify the release first (https://github.com/emberinfer/Ember/blob/master/docs/SIGNING.md, signing key fingerprint `d3b07085781f2d4d75de6caefa6e1dc9cd4eadeec10326b2b0c20eb03254eabb`).

```sh
# 1. Download ember-0.2.0-linux-{amd64,arm64}.tar.gz + SHA256SUMS(.sig)
#    from https://github.com/emberinfer/Ember/releases/download/v0.2.0 and verify per SIGNING.md, then:
tar -xzf ember-0.2.0-linux-amd64.tar.gz && cd ember-0.2.0-linux-amd64
./install-release.sh --role node --prefix "$HOME/ember" --python python3.12

# 2. Fetch the model (weights are never distributed by the network;
#    they are verified against the on-chain manifest hash)
"$HOME/ember/venv/bin/python" - <<'PY'
from huggingface_hub import snapshot_download
snapshot_download("Qwen/Qwen2.5-1.5B-Instruct", revision="989aa7980e4cf806f80c7fef2b1adb7bc71aa306",
                  local_dir="~/models/Qwen2.5-1.5B-Instruct",
                  allow_patterns=["*.json", "*.txt", "*.safetensors"])
PY
```

Set the fields of the installed `config/node.env` to this network's published parameters (all from https://emberinfer.org/network.json):

| Field | Value |
| --- | --- |
| `EMBER_COORDINATOR` | `relay.emberinfer.org:39091` |
| `EMBER_TLS_FINGERPRINT` | `f55c4c10cf3c5b1bad74a9fb5310eceb1c6ffb77bfed139c3dd2e93f9de53642` |
| `EMBER_MODEL_CHAIN` | `ember-qwen2.5-1.5b-s22-cpu-v1` |
| `EMBER_MODEL_PATH` | your local model directory from step 2 |
| `EMBER_SCHEDULER_ID` | `8b608c779fa64855714e7c81559acf866699a4b129f8481136ed109962ab0c0a` |
| `EMBER_CHAIN_RPC` | `http://relay.emberinfer.org:39657` |
| `EMBER_LEDGER_CHAIN_ID` | `ember-s23-staging` |
| `EMBER_GENESIS_SHA256` | `eb1ec84d9c9fa382f59b559b4bac418fa014d10ea4597bb5ec00afb6f712bf23` |
| `EMBER_MANIFEST_SHA256` | `4ec83c765b49ecd178eb1a2f7a6c9db5cf9d13285bb58ee0bc671643edc05061` |

```sh
# 3. Identity, funding, start
"$HOME/ember/bin/ember-node" id --state-dir "$HOME/ember/var/node"   # prints your address
curl -fsS http://relay.emberinfer.org:39095/testnet/faucet -H 'Content-Type: application/json' \
  -d '{"account":"<your-address>"}'                                  # faucet funds the stake
"$HOME/ember/bin/ember-role" node "$HOME/ember/config/node.env"        # stakes, registers, serves
curl -fsS http://127.0.0.1:19192/readyz                                # readiness (loopback only)
```

External CPU serving is slow for long requests; start with short ones. Registrations expire by height (default TTL 200000 blocks) and renew while you serve. To exit: stop the process and disable restarts, wait for registration expiry and outstanding holds to finish, then recover stake with `ember-node exit --action status|unbond|claim` (full procedure in the Quickstart).

Deploying nodes at scale or for an organization? Partnerships and coordination: emberinfer@proton.me.

## Path 3 — Audit

Auditors replay committed token prefixes of sampled requests under the signed profile policy and sign verdicts; a rejection needs confirmation by a different assigned auditor, and disagreement cannot slash. Auditing is a node role: install as in Path 2 and set `EMBER_AUDIT_ROLE=true` in the generated config **before the first join** (Quickstart, "Network parameters"), then fund, register and run the same way. Removing the role takes effect at registration expiry. Auditors are paid from the 15% auditor share of the settled fees of the requests they audit. Cross-runtime verdicts are observe-only in the current build.

Note what auditing sees: in Phase 0 an assigned auditor can see the plaintext of the requests it replays. Audit only if that is acceptable for your participation; users are told the same on the chat page and in the guide.

Interested in auditing as an organization? Partnerships and coordination: emberinfer@proton.me.

## Limitations

- Testnet only; Spark here is valueless test credit and carries over to no other network.
- Validators: single operator, static membership. No third-party security audit has taken place.
- Gateway account custody is centralized in the current build (one consumer account per gateway); the prepaid website model exists because of it.
- Privacy Phase 0 as above; no confidential-inference or hardware-attestation claim is made.
- Abuse controls: per-account and per-source faucet limits, gateway rate limits, bounded holds with height expiry.

Deeper reading: public network & trust model https://github.com/emberinfer/Ember/blob/master/docs/PUBLIC_NETWORK.md · pricing https://github.com/emberinfer/Ember/blob/master/docs/PRICING.md · audit design https://github.com/emberinfer/Ember/blob/master/docs/AUDIT_DESIGN.md · disclaimer https://github.com/emberinfer/Ember/blob/master/docs/DISCLAIMER.md
