http://localhost:8082/swagger/index.html.
Contract minimums
| Item | Value (wei) | Display |
|---|---|---|
providerMinStake | 200000000000000000 | 0.2 MOR |
modelMinStake | 100000000000000000 | 0.1 MOR |
marketplaceBidFee | 300000000000000000 | 0.3 MOR |
bidPricePerSecondMin | 10000000000 | 0.00000001 MOR/sec |
What you’ll need
| Item | Example |
|---|---|
| Provider wallet | 0x9E26Fea97F7d644BAf62d0e20e4d4b8F836C166c |
| Public endpoint | server.example.com:3333 |
Random modelId (32-byte hex) | 0xe1e6e3e77148d140065ef2cd4fba7f4ae59c90e1639184b6df5c84 |
ipfsCID (32-byte hex) | 0xc2d3a5e4f9b7c1a2c8f0b1d5e6c78492fa7bcd34e9a3b9c9e18f25d3be47a1f6 |
| Model name | CapybaraHermes-v2.5-Mistral-7b |
Bid pricePerSecond | 10000000000 (0.00000001 MOR) |
Steps
Authorize the Diamond contract
POST /blockchain/approve — set spender = <DiamondContract> and amount ≥ 0.6 MOR (in wei: 600000000000000000) to cover provider stake + model stake + bid fee.Register your provider
POST /blockchain/providers — set addStake (≥ 0.2 MOR; 10000 MOR for a subnet provider) and endpoint (your publicly accessible host:port, no protocol).Add your model to IPFS
POST /ipfs/add — capture the returned Hash (this is your ipfsCID). Then POST /ipfs/pin with the same hash to keep it pinned.Create the model on chain
POST /blockchain/models with:modelId: random 32-byte hex (becomes the on-chain id paired with your providerId).ipfsCID: from the previous step.Fee: model fee.addStake:0.1MOR minimum.Owner: your provider wallet.name: human-readable model name.tags: array of strings.- TEE providers must include
"tee"(case-insensitive) to opt the model into the two-hop attestation chain. - Other common tags:
llm,embedding,stt,tts.
- TEE providers must include
modelID from the JSON response — this combines your requested modelId with your providerId and is required for models-config.json and bids.Update models-config.json
Add the new on-chain
modelID (the combined value) to your models-config.json and restart the proxy-router. See models-config.json.TEE tag deeper context
Tagging the modeltee engages two independent verifications on every session and prompt — one each side:
- Phase 1 (consumer → your P-Node). Any v6.0.0+ consumer proxy-router will verify your P-Node’s TDX attestation (CPU quote, TLS pinning, RTMR3 of the
-teeimage) at session open and on every prompt before forwarding inference. - Phase 2 (your P-Node → backend). Your v7.0.0+ P-Node will verify the backend LLM your model’s
apiUrlpoints to — CPU TDX quote, TLS pinning, RTMR3 replay of the backend’sdocker-compose.yaml, CPU-GPU nonce binding, and NVIDIA NRAS GPU attestation — at startup and on every prompt.
tee tag are treated as standard providers; neither hop runs.
See TEE overview and TEE reference.
Where things show up afterward
- Your provider on chain:
GET /blockchain/providers - Your model on chain:
GET /blockchain/models - Your bids on chain:
GET /blockchain/bids - Live network listings: active.mor.org
- Operator dashboard: myprovider.mor.org
Choosing a modelId (community convention)
The contract does not enforce uniqueness of model names. You can register a modelId with the same name and ipfsCID as an existing model — the marketplace will simply have multiple entries pointing at the same logical model. As a result, snapshots like active.mor.org/active_models.json often show many entries for popular names with one provider each.
Recommended practice:
- Reuse an existing
modelIdwhen you’re hosting the same logical model someone else has already registered. This keeps the marketplace clean, gives consumers a single dropdown entry with multiple providers (good for failover and competitive pricing), and avoids fragmenting reputation data. - Mint a new
modelIdonly when your model is genuinely different (different weights, different fine-tune, differentipfsCID).
modelId (the contract takes the same value as input — see how the on-chain modelID is getModelId(modelOwner, requestedModelId) in ModelRegistry.sol; the resulting on-chain id will still be unique to your provider, but consumers can match on modelName + ipfsCID).
Pausing or temporarily disabling a model offering
To stop offering a model without deregistering it (so you keep themodelId, keep the model stake bonded, and can resume cheaply):
0.3 MOR marketplaceBidFee again — see pricing).
If you want to completely remove a model: delete all of its bids first, then call modelDeregister to recover the 0.1 MOR model stake. The contract refuses modelDeregister while any bid for that model is still active.
How and when you get paid
For typical staked sessions, the protocol pays you insidecloseSession via _rewardProviderAfterClose, with the funds coming from a separate protocol fundingAccount (via transferFrom), not from the consumer’s stake in real time. There is no separate “session claim” step for the standard flow — the payment for time actually used hits your provider wallet in the same transaction that closes the session.
What this means for you operationally:
- Keep your provider wallet ready to receive MOR; you don’t need to call a claim function.
- For the direct-payment carve-out (a separate flow some sessions use), behavior differs — see the contract source and tech.mor.org/session.html for the canonical breakdown.
- If
closeSessionever fails because the protocol funding account is empty or under-approved, no provider gets paid until operators top it up — that’s a network-wide failure mode, not a per-provider one.

