Compute Marketplace
What is shipped and how the pieces fit: the coin, the ledger that agrees it, the backends that do the work, and the wrapped mirror on Ethereum.
A job, start to finish
Native MATRIX, the settlement coin
Buyers pay in it, providers earn it, and it is the single source of truth for balances and supply. One currency end to end, not a separate notion of credits.
- Symbol MATRIX, 9 native decimals on the Matrix L1
- Supply capped at 1,000,000,000 whole MATRIX; balances live on the consensus ledger
- Public launch provider emissions are zero; providers earn user-paid MATRIX at their snapshotted quote
- All settlement is applied deterministically once a consensus block commits
The bridged wrapped ERC-20 mirror
- Lock to mint - a consensus-ordered lock of at least 100 MATRIX moves the full native amount into escrow; bridge locks pay no protocol fee
- Fixed EVM attestors - WrappedMatrix verifies a threshold of the immutable secp256k1 addresses selected at deployment. That committee is independent of the dynamic native bonded-open validator set; joining native consensus does not grant mint authority
- Collect, then submit -
matrix bridge attestationasks the configured endpoints for signatures over one committed lock. The user submits the mint transaction on Base and pays Base gas from their wallet; there is no gas relayer - Burn to unlock - a confirmed Base Burned event becomes a native-consensus attestation. Escrow release is always ordered on the native chain and, with multiple validators, occurs only in the committed block where native voting power crosses quorum
- Two independent quorums - the fixed contract committee gates EVM minting, while the current native validator set gates burn release. The two sets may overlap operationally but never update each other automatically
- Native has 9 decimals and wMATRIX has 18, so one native base unit equals 1e9 wrapped base units. The production contract mint ceiling is 6% of native maximum supply, while every minted unit still requires matching locked collateral
- The 1:1 relationship is MATRIX-to-wMATRIX backing only. It is not a USD, USDC or stablecoin peg and does not stabilize market price
- Base Sepolia (84532) is the rehearsal target and Base (8453) is the production target. Configuration support is not a live-deployment claim: verify the exact contract address, code and endpoints before signing
Fast consensus chain
- ed25519 validator set, round-robin leader, no proof-of-work
- A quorum is more than two thirds of the set, in both voting phases
- Round timeouts rotate the leader, and the next leader must re-propose the block that last reached a polka, carrying the polka as proof
- Committed blocks are SHA-256 hash-linked into one chain every node shares
- A node that missed a block fetches it from a peer with the quorum that committed it
Consensus is the authoritative, globally agreed ledger for marketplace settlement. Both the compute marketplace and the LLM inference marketplace settle buyer to provider through consensus in native MATRIX by default. The earlier per-node pairwise settlement and the direct token-chain transfer remain as separate, non-default primitives for point-to-point transfers, but the marketplace flows no longer use them.
LLM inference backends
Inference is a pluggable backend, so a provider can contribute compute in two ways:
- Local runner - serve a model from your own hardware through an Ollama-style local HTTP API. A GPU-free echo backend runs the whole flow for testing.
- Provider-API proxy - proxy requests through an OpenAI-compatible API. The key is read from an environment variable and never hardcoded or committed.
Jobs reserve capacity against the provider's current manual MATRIX quote. The reservation snapshots price per unit, quote identity/version, observation time and expiry, so a later provider refresh cannot reprice accepted work. Stale quotes are rejected before work starts; there is no stablecoin peg or automatic DEX oracle. The backend runs, and settlement then moves native MATRIX buyer-to-provider through consensus, capped at the reserved snapshot.
The OpenAI-compatible route
A node serves POST /v1/chat/completions and GET /v1/models on its HTTP endpoint (port 9093 by default), so reaching the marketplace is a one-line change:
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:9093/v1", # your node, or any node
api_key="<your matrix api key>",
)
r = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": "hello"}],
)Three things the OpenAI protocol does not carry, and where they come from here:
- Who pays - the API key. OpenAI identifies the caller by the key alone, so the key names the on-chain account to charge (
accountundersecurity.api_keys). The balance stays on the ledger; the key is a proof of account ownership, not a stored credit balance. A key with no account cannot buy inference. - Which provider - the model. The request is routed to the cheapest provider advertising that model with capacity to spare, ties breaking on provider id so two identical requests do not scatter at random. The response adds a
providerfield naming who served it, which an SDK ignores. - How much to reserve - an upfront estimate from the request. The settled charge comes from the tokens the backend actually reported, so the estimate decides the reservation and never the price.
"stream": true works, as server-sent events: a role frame, a content frame per delta, a stop frame, then the usage and [DONE]. Every frame is flushed as it is produced. A backend that cannot stream is not hidden - the final frame carries streamed_one_shot so a UI knows the whole answer arrived at once instead of pretending there was a typing effect. A failure after the first frame travels in the body as an error frame, because the status is already 200 by then and a stream that merely stopped would look complete.
Paying with your own key
There are two ways an inference job gets paid for, and which one you want depends on who holds the key.
- Hosted -
SubmitInferenceJobthenFulfillInferenceJob. The node signs the payment on the buyer's behalf with a key it already holds. Right for a node you run yourself; it makes the operator a custodian of every caller's balance on a node other people use. - Client-signed -
RunInferenceJobthenSettleInferenceJob. The node needs no key for you at all. - Hosted and streamed -
StreamInferenceJob, or"stream": trueon the OpenAI route. Streaming is deliberately unavailable on the client-signed path: there the completion is withheld until the invoice is signed, and streaming the answer out before asking to be paid gives away the only thing holding the buyer to the bargain.
The obvious approach, pre-signing the transfer the way a wallet transfer does, cannot work here, and the reason shapes the design: a transaction signs over an exact amount, and the price of an inference is not knowable until the work is done, because it comes from the tokens the backend reported. Nobody can sign for a number that does not exist yet.
So the flow is sign-the-invoice. RunInferenceJob reserves capacity, runs the model, and returns the exact transfer to sign - without the completion. You sign it and call SettleInferenceJob, which verifies the signature, checks every signable field against the invoice, submits it to consensus, waits for it to commit and apply, and then hands over the completion.
Withholding the completion is the enforcement, because the provider has already done the work. Their exposure is the compute for one job per defecting buyer, bounded further by the affordability check that ran when capacity was reserved - the same exposure any metered API carries, and the price of not holding the buyer's key. A job whose buyer never signs has its reservation released, so nobody can park a provider's capacity for free.
A valid signature is not sufficient on its own. A transfer of one base unit to an account you control verifies perfectly, so every field of the signed transfer must equal the invoice's or the settlement is refused.
Wallets, and MetaMask
MetaMask works fully for wMATRIX: it is a standard ERC-20 with EIP-2612 permit, so holding, sending, approving and swapping it need nothing from us. What MetaMask cannot do is sign a NATIVE transaction, because native accounts are ed25519 and MetaMask is secp256k1. That is a structural mismatch, and it is the same one Solana, Near, Aptos and Sui all have.
Rather than leave people with two wallets, a native account can be controlled by an Ethereum key. There are two kinds of account now:
<64 hex>- an ed25519 account, unchanged byte for byte.eth:0x<40 hex>- controlled by that Ethereum address. It funds, spends and reads like any other account.
An eth account signs EIP-712 typed data, which is the only thing MetaMask signs, and is also what makes the prompt readable rather than a hex blob. The domain carries no chainId and no verifyingContract - claiming an EVM chain id we do not own would squat on someone else's domain separator - so a signature made here has no meaning on any EVM chain.
The two kinds are told apart by the ACCOUNT ID, not by a field in the signed payload. That matters: adding a scheme byte to the canonical transaction bytes would have invalidated every ed25519 signature ever produced and re-hashed every committed block. The digests are pinned against ethers v6's own output in the tests, because agreeing with a real Ethereum library is the only thing that proves a wallet will produce a signature the node accepts.
For an ed25519 wallet there is now a 12-word BIP-39 recovery phrase and an encrypted keystore, derived at the SLIP-0010 path m/44'/9004'/0'/0'. See the CLI reference.
Reading the directory
Every figure in the marketplace directory is read from the chain the answering node holds, or observed by that node itself. None of it is reported by the seller: an announcement carries no uptime, no latency and no rating, because those are exactly the numbers a seller can type anything into.
Staked is capital the seller has posted on this chain, and it cannot be pulled on demand - the chain holds a bond for a minimum number of blocks after it is posted. It does not make anyone honest and cannot be taken away for bad service: no protocol can judge whether a completion was really the model advertised. What it does is make a listing cost money, which is what stops one attacker from filling the directory with cheap fake sellers.
Settled figures are transfers on the chain that node holds, not claims by the seller. A settlement is an ordinary transfer, so they count every payment the account received - a seller can pay itself. Payers is the harder one to inflate: it costs a funded account each.
The badge means one checkable thing: the account this chain names as its maintainer signed a statement that it operates that node. It is an identity claim, not a rating - it does not say those sellers answer better, and a reader who does not trust that account should ignore it. It cannot be forged: the signature is checked against consensus state, which only the current maintainer's own signature can rotate, and it expires so a badge cannot outlive the arrangement it describes. It exists because a new network is mostly strangers with no settled history to tell them apart, and somebody has to go first; the honest way for the people running one to do that is to run sellers themselves and say so.
There is no uptime column because an announcement carries no uptime. A number a seller publishes about its own reliability costs nothing to inflate, so the protocol does not carry one and the directory will not invent one.
It is one node's view. The directory is read from a single node. That node heard these announcements and holds the chain the stake and settled history come from, so a different node may have heard others.
Amounts are exact. The chain has nine decimals, and a settled total really can end in a few base units, so the directory shows what the ledger says rather than a rounded figure - the fraction is simply set quieter than the digits that carry the magnitude. Per-unit prices are quoted per million units, which is an exact shift of the decimal point.
None of this says the answers are any good. Judge that yourself, on a small job, before sending a large one.
Matrix Console
Matrix Console is a Tauri + React + Vite desktop app that connects to a local matrixd node to observe and control the marketplace from one window: node connection, providers, jobs, the native MATRIX wallet and settled ledger, the consensus chain, and LLM inference.
The React frontend builds and runs everywhere. Packaging the native desktop bundle additionally needs the WebKitGTK/libsoup system libraries.