Mainnet Readiness
Status: the mainnet is live in production with small limits; the hardening below is not done. Last reviewed 2026-10-23.
The mainnet (chain 1000) has been open to every account since 2026-10-05 and runs in production: real USDT, at most $100 per top-up and $200 per day, and withdrawals of $25 to $50 (open since 2026-10-16). It runs without parts of the gate below, on purpose, with limits small enough that a total loss would be acceptable: the mint and payout keys are plain keys on the server, the three validators run on one host and are operated by one person, no real payout has been made yet, and nothing has been audited. Use only what you can afford to lose. See Environments for the addresses and the limits.
Clutch also runs a public alpha testnet. The CLT on it is backed by Tron Nile testnet USDT, which has no value and cannot be bought.
This page exists because "when is the mainnet hardened?" deserves a better answer than "no fixed date". Below is what has to be true before the mainnet's limits are raised, why each item matters, and what counts as evidence that it is done. It is the public half of a checklist maintained in the treasury repository, which carries the operational detail.
How to read this
| Severity | Meaning |
|---|---|
| Blocker | Real funds cannot be accepted until this is done. No cap is small enough to work around it. |
| Required | Must be done before a public launch. May be deferred while limits stay small enough that total loss would be acceptable. |
| Recommended | Reduces risk. Skipping is a decision to record, not a gap to hide. |
Every item names what closes it. An item is closed by an artefact someone else can inspect, not by intent.
Today's mainnet is a recorded exception to the first row. The maintainer decided to run it before the key custody and the payout rail are closed, and the caps are the bound on the loss. The rule in the table is the rule before the limits are raised.
The gate
Five things must all be true before the mainnet's limits are raised. The mainnet runs today without items 1, 2, 3 (independent operators) and 5, on purpose:
- The mint key and the payout key sit behind a KMS or hardware boundary, with a rehearsed recovery.
- The payout rail has been proven on mainnet, with a real receipt behind the fee.
- The chain runs a fresh mainnet genesis, with authorities under independent operators.
The treasury ledger has off-host backups and a restore that has actually been performed.Met 2026-09-15.- More than one person can operate and halt the system.
Where each one stands on 2026-10-06:
| Item | State |
|---|---|
| 1. Keys behind a boundary | Waived for now. Both keys are plain secrets on the server. |
| 2. A real payout receipt | Open. The payout wallet was activated on 2026-10-16. The first real withdrawal, and so the first receipt, has not been made yet. |
| 3. Fresh genesis, independent operators | Half met. The mainnet genesis is fresh: started 2026-09-19 and replaced on 2026-10-05 and twice on 2026-10-06, each time before any CLT existed. The validators share one host and one operator, by choice for now. |
| 4. Backups and a performed restore | Met 2026-09-15. The mainnet restore was rehearsed on 2026-10-05. |
| 5. More than one person | Open, by choice. |
Everything below expands these, plus the product, review, and regulatory work around them.
What happens next, in order
Still to do first, the first real withdrawal is made (the payout wallet was activated on 2026-10-16). That withdrawal's receipt is the first mainnet measurement of the payout fee (item 2).
Before any limit is raised, three things, each one an exception the mainnet runs under today:
- The payout key goes behind a KMS boundary, and the reserve goes back to sitting mostly in custody, with the payout wallet holding only a float.
- The mint key goes behind a boundary again. The mint authority is a genesis value, so this means a new chain. That is free only while no CLT exists: the chain reset refuses for good once any CLT has been minted, and after that the move needs a planned migration. This is why it is cheaper to do early.
- A second person who has rehearsed halting minting.
Before the limits go higher still, the validators move to independent hosts and operators, after the move has been rehearsed on a throwaway network, and a decision is made on reputation.
Several of these physically cannot start until another has finished. That is most of the answer to "when is the mainnet hardened?", and it is why the honest answer is an order rather than a date. Three constraints shape it.
The genesis is final. Consensus parameters are committed into the genesis hash and compared by peers at handshake, so they cannot be changed afterwards without starting a new chain. That includes the mint authority's address, and it is why the mainnet chain was replaced three times before any CLT existed: once for the mint key on 2026-10-05, and twice on 2026-10-06 for the wallet signatures, which are a consensus change. Once CLT exists, a change like that needs a planned upgrade of every validator instead.
A second person gates more than it looks. A real key ceremony requires two people, because its real subject is testing that access recovers — a second principal, in a separate identity, signing from a machine that has never held the first one's credentials. So "find another operator" sits upstream of the keys.
The payout fee cannot be set before a mainnet payout exists. Tron's Nile testnet sponsors its own energy for the test USDT contract, and its GasFree relay is not mainnet's, so no testnet payout says what a mainnet one costs. The first mainnet withdrawal is therefore the first real measurement, and the fee follows it rather than preceding it. See Redemptions.
What "closed" means here
Several items below are marked closed against the current testnet. Closed against a testnet is not closed against mainnet, and the distinction is not pedantry: what gets verified is a specific bucket, a specific passphrase, a specific alert destination. The backup rehearsal and the alert route both have to be performed again against the real stack.
The bar for each is evidence that something worked, not evidence that it was configured. That wording is deliberate. Over two days of building the monitoring for this, four separate signals loaded cleanly, reported no error, and measured nothing — a config include matching no files, an alert rule whose query could never match, a credential file the alerting process could not read. Every one of them looked healthy from outside. An untested control is a belief, and the belief is usually wrong in the way that only shows up on the day it matters.
Key custody
Blocker. The mint authority is the only key that can create CLT, so its compromise means unbounded issuance against a fixed reserve. Today it is an environment variable on the server, as is the payout key, on the testnet and on the mainnet. On the mainnet that is a real exposure: someone who gets into the server could mint CLT without limit and take the reserve, and the pilot's small limits are what keep that loss small. That is a tracked gap rather than an oversight: ChainSigner and PayoutSigner already exist in the code as swap boundaries for a KMS-backed signer, and the named blocker is that signer plus a real key ceremony and tested recovery. See Security for the full key inventory.
One absence is deliberate in the design: nothing in the stack can spend from the reserve custody address. That is why redemptions are paid from a separate, bounded float instead, so the worst case for a compromised service is the float balance rather than the reserve. The mainnet gives it up on purpose, and the testnet has been configured the same way since 2026-10-05, because of cost and the early stage of the network: all deposits are swept into the payout wallet, whose key is on the server, and the custody address stays empty. So on the pilot the worst case for a compromised server is the whole reserve, and the small limits bound how large that can be. See Clutch Treasury Overview.
The chain supports M-of-N minting, described below, but the mainnet genesis commits one mint authority and no co-signers. That was decided on 2026-09-18, because a second independent key store was not affordable. Since 2026-10-05 that one key is a plain secret on the server. The four-eyes rule, the mint caps and the halt breaker are in the treasury service, off-chain, so they stop a mistake in the treasury and not someone who holds the key. Adding co-signers later needs a new chain, because the mint authority and the co-signer set are committed in the genesis.
Multi-signature minting shipped on 2026-09-11, and it addresses the larger half of this item. Until then a Mint was authorised by a single address, while every other control on minting — the two-approver rule, the per-transaction cap, the daily cap, the halt breaker — lived off-chain. A holder of that one key could submit a mint straight to a node and none of them would run. Non-exportable key storage lowers the chance of theft; it does nothing about what theft would mean.
The chain now supports M-of-N: a mint is authorised when it is submitted by one member of an authority set and carries further approval signatures from distinct other members, checked by consensus rather than by an application. Approvers sign a digest covering the chain, recipient, amount and the off-chain payment reference, so an approval for one mint cannot authorise another, and the treasury service that collects those signatures never holds the keys that make them.
The configuration designed on 2026-09-12 was three authorities, any two of which must sign, with the three keys deliberately held in three separate places: one reachable by the treasury service, one under separate credentials elsewhere, and one offline as a cold spare. Three keys in one account would be a two-of-three on paper and a one-of-one in practice. It was set aside on 2026-09-18 for a single key, as the box above says, and it stays the reference design for a later chain.
Closed by: signing through KMS in the mainnet configuration, key material that has never existed outside it, a written ceremony record, and a recovery rehearsal in which both keys were restored into a fresh environment and used to sign.
The payout rail
Blocker. The redemption payout path cannot be fully tested on the current testnet, and this is worth understanding if you are building on Clutch. Nile's test USDT contract sponsors its own energy, so every Nile payout reports zero energy fee whether or not energy delegation is working. A payout made before delegating reads identically to one made after. Mainnet USDT makes the sender pay, so the first mainnet payout is the first real test of the energy model. No mainnet payout has been made yet: withdrawals open once the payout wallet is activated, and the first one is that measurement.
The redemption fee follows from that. It was measured rather than chosen, from the energy a TRC-20 transfer burns, the chain's energy price, and the TRX price on the day. That energy price is a TRON governance parameter which has already halved once, so the fee has to be re-measured against mainnet rather than scaled from the testnet number. Redemptions documents the model.
A single redemption is already bounded twice, in two services that do not share the value, so a request the signer would refuse cannot become a burn nobody can pay. Those caps are the loss ceiling for every failure above them.
Closed by: a mainnet payout receipt showing sender-supplied energy, a fee set from a dated mainnet measurement, and mainnet caps with a written rationale naming the worst case each one bounds.
Chain and validators
Blocker. Consensus parameters, including the network id and the testnet flag, are committed into the genesis hash and compared by peers at handshake. Mainnet is therefore a new genesis, not a configuration change, and it must pre-mint nothing. That half is done: the mainnet (chain 1000) started from a fresh genesis on 2026-09-19 that pre-mints nothing, and every replacement since has done the same. See CLT Economics.
Aura is an authority round-robin, so the validator set is permissioned by construction. A hardened mainnet needs authorities that do not share an operator or a failure domain, each with its own key. The mainnet's three authorities run on one host and are operated by one person, so the host is the chain: if it is lost, the chain is lost with it. The pilot's own chain holds only what users top up within the small limits.
Nothing was watching whether the chain was producing at all until 2026-09-14. The testnet halted, stayed halted for most of a day, and the first alarm was a person noticing the block explorer was empty — three layers below the fault. Alerts covered the money path and not the chain that money path reads from, which is the wrong way round: a treasury reading a frozen chain believes a frozen supply and judges its reserve against it.
Liveness is now alerted on directly. Aura authors an empty block every slot when there is nothing to include, so height advancing is a heartbeat rather than a measure of traffic — a quiet chain still climbs, and one that stops climbing is broken. That property is what makes the alert possible, and it is worth stating because a consensus that produced blocks only on demand would need an entirely different signal. Validators disagreeing about the height is alerted separately: a node that has fallen behind still answers queries, with its own stale number, which is harder to notice than one that has stopped answering.
Closed by: reviewed and recorded genesis parameters, every node reporting the same genesis hash, block production observed continuing with one authority stopped, a key rotation procedure rehearsed on a throwaway network, and the liveness alert delivered to a human rather than only to a dashboard.
Durability and recovery
Met 2026-09-15. The treasury ledger is the off-chain half of every deposit and redemption. The chain records the mint and the burn; it does not record which off-chain payment a mint answered. Losing that ledger means losing the ability to honour redemptions, so it needs the same seriousness as the keys.
The backup and restore path was rehearsed against the testnet on 2026-09-12, and the rehearsal found the backup broken. The first attempt stopped two lines in with no output at all, because reading an unset optional setting aborted the whole script under strict shell error handling. That was not a theoretical fault: the nightly job had already run once and failed exactly that way, silently, on a host where nobody was watching. Had nobody rehearsed, the first sign of trouble would have been a restore that found no backups.
It is fixed, and the failure path reports properly now. The second attempt dumped both databases, encrypted them, decrypted them, restored each into a throwaway copy with the expected row counts, and dropped the copies. Nothing touched a live database at any point.
This is the argument for the item rather than an aside. A backup job that has never been exercised is a belief, not a control, and the belief is usually wrong in a way that only shows up on the day it matters.
Closed on 2026-09-15. Encrypted dumps now run nightly to off-host object storage, and the verification that closed this was not a loadable dump — it was a dump fetched back out of that storage, decrypted with the real passphrase, restored into a throwaway database, and reconciled green against the real chain and real custody. Row counts prove a restore is not empty; they do not prove it is coherent, and only the second thing is worth anything.
That reconciliation runs in a mode that starts no background workers at all. An ordinary instance of the treasury service would start the sweeper, the chain outbox and the payout workers, every one of which acts on chain — so a service pointed at a copy of the ledger would re-broadcast transactions already submitted and re-sweep addresses already swept. Verifying a backup must not be able to move money, and the safe path has to be built deliberately rather than assumed.
The rehearsal found a real discrepancy, which is the argument for the item rather than an aside. The first run came back not-green, and so did the live ledger, with identical numbers — which is what proved the restore faithful rather than broken. The gap was a single mint that had been submitted to the chain and never confirmed, sitting in a state nothing retried, nothing timed out, and nothing checked. It had been raising an alert for a day. A backup exercise found it because reconciling a restored ledger asks a question nobody had asked of the live one.
The same restore was rehearsed against the mainnet treasury on 2026-10-05, from its own off-host storage with its own passphrase, and reconciled clean. The ledger was still empty then, so it proved the path rather than the data; it will be run again after the first real deposits.
Both defects behind it are fixed: a submission that is not confirmed within a bounded window is now re-queued, safely, because the chain refuses a duplicate mint against the same reference; and the deposit watcher's position is now published and alerted on when it drifts above the chain head, a state a chain reset produces silently.
Abuse controls
Required. Anyone can create a keypair, so every authenticated endpoint is effectively public. Rate limits belong on those endpoints and on token issuance before a public launch. Deposit addresses are permanent and polled on a rotation, so the relationship between how many exist and worst-case detection latency needs a measured ceiling rather than a discovered one. See Deposits for how polling works.
The token-issuing endpoint was rate limited and then measured against the testnet on 2026-09-13. The per-identity limit refused exactly the request after its allowance, both runs. The endpoint-wide limit held inside a window, and the service stayed up while that endpoint was saturated, which is the property that matters: a limiter that protects one route by taking the process down would be worse than none.
The measurement also corrected something the code claimed. The endpoint-wide limit uses a fixed window, so its counter resets at the boundary and a burst spanning one gets up to twice the configured number. A comment had dismissed that as uninteresting; the same burst was refused on one run and not at all on the next, purely on timing. The limit is unchanged, because twice a number chosen well below what causes harm is still well below it, but it is now described accurately rather than optimistically.
A per-client limiter now also runs at the edge, in front of every Clutch hostname, as of 2026-09-14. It refuses nothing yet, deliberately: it evaluates each request, records what it would have rejected, and serves it. A rate argued from how many requests a page load makes is a guess, and guessing low means turning away real people with no application log to explain why — so the measurement comes before the enforcement, and the enforcement is one line.
Keying it correctly was the substance. Behind a CDN the immediate peer is the CDN, so limiting on it would put every visitor in one bucket, and trusting a forwarded header outright is what the application deliberately refused to do — a spoofable one lets an attacker both create unlimited buckets and lock a chosen person out. The edge matches on the real peer address first and honours the forwarded header only when the request genuinely arrived from the CDN, which is the distinction the application had no way to make.
Closed by: limits recorded and shown to hold under load, the edge limiter enforcing with a measured period behind it, and a documented ceiling on address growth.
Client-side key handling
Closed 2026-10-06. It was a blocker for any app holding real funds.
The reference demo app used to generate or import keys in the browser and store them in plaintext localStorage, and the mainnet served that same app. It no longer holds a key, on any network. The user's own wallet (MetaMask, Trust Wallet or TronLink) keeps the key and signs a short readable text after the user approves, and the node and the Hub API accept that signature next to the signature of a key. Key generation, import, the encrypted backup and the "never put real funds behind a key created here" notice are gone, and the new version deletes the plain-text keys that older versions left in the browser. The SDK's design allowed this from the start: keys never leave the client, so a real key boundary substitutes without changing how transactions are built. See Signing and Encoding and SDK Usage.
One limit remains, and it is not hidden:
- A wallet shows the text it signs, not the ride. The app says what each prompt is for before it opens, and the SDK checks the unsigned transaction against what was asked before it asks the wallet. Readable typed data (EIP-712) would let the wallet show the ride itself.
A second limit listed here at first, no WalletConnect, is gone: a wallet on a phone can now scan a QR code shown on a computer, or approve a sign-in started in the phone's own browser.
Closed by: the reference app holding no key and signing only through the user's wallet, with the node and the Hub API accepting that signature.
Market operations
These decide whether a real ride market is usable. They do not endanger the reserve.
Dispute resolution — built on 2026-09-12, switched on at mainnet genesis. The gap here ran the opposite way to how it is usually described. A rider is already protected: accepting an offer holds the whole fare, payment is released in instalments, and cancelling returns the unpaid remainder, so a rider who stops paying loses only what they released. The party with no protection was the driver, against a rider who takes the ride and never releases the rest. The driver's only move was to cancel, which returned the money to the rider.
Two hours after a ride is accepted, that same cancellation now pays the remaining held fare to the driver instead. Inaction used to favour whoever owed money; it now favours whoever is owed. The window is a consensus parameter fixed in the genesis, not something an operator can change afterwards.
Stated plainly, because it is the limit of what this does: it closes silent non-payment. A rider acting in bad faith who actively cancels every ride still avoids paying. That behaviour is visible on the public ledger and is what reputation below is for. Cancelling inside the window was deliberately left free, because charging for it would penalise exactly the rider this protects.
Riders still give up card-issuer chargebacks by signing payment directly, and that remains a real trade rather than something the above removes.
Reputation — required. No driver or rider scoring exists, so nothing distinguishes a first-time counterparty from a repeatedly bad one.
Matching — recommended. Matching is simple, with no surge, pricing engine, or geospatial optimisation. This becomes an operational problem before it becomes a technical one, so the volume at which it needs work should be chosen rather than discovered.
Test coverage
Test depth is uneven and follows the money, which is the right priority but leaves gaps: coverage is deepest in the treasury and thinnest in the Hub API, which sits on the path every user takes. Failure-branch tests on the mint, burn, sweep, and payout paths — including the ambiguous-payout branch that deliberately stops and pages a human rather than retrying — are what close this, path by path, rather than a single audit event.
What already holds
Stated so the sound parts are not assumed provisional. These were designed for this and are in place today:
- The deposit mnemonic exists in one service. The service that hands out deposit addresses holds only an extended public key, which derives receive addresses and cannot spend. Owning it does not move a deposit.
- The sweep endpoint takes an address index and nothing else — no destination, amount, or contract — so it cannot be turned into a second payout path.
- Reserve custody is unreachable from code, which is why payouts come from a float. With one wallet that float holds the whole reserve, so this no longer bounds a loss on the mainnet: see Key custody above.
- Redemptions are bounded twice, in services that do not share the value.
- Ambiguous payouts stop rather than retry. Only a reply proving nothing was broadcast returns a redemption to the queue; anything else pages a human. That accepts a stuck redemption to avoid a double payment.
- Minting has four-eyes approval, a per-transaction cap, a daily cap, and a manual halt.
- Genesis pre-mints nothing. Every CLT that exists was minted against a verified deposit.
- Keys never leave the client for ride transactions. The Hub forwards signed transactions and cannot alter one without invalidating the signature, and the SDK can verify a hub-built transaction against what the app asked for before signing it. See Signing and Encoding.
Where help lands
Several of these are genuinely open problems rather than known work someone is already doing, and they are the most interesting parts of the system. Dispute resolution and reputation are design problems first, and the design is not settled. Test depth on the Hub API path is contributable today. So is review of the signing and encoding path, which is fully specified and does not require access to anything.
The discussions are open, and the FAQ covers what is shipped versus planned.
What this page is not
It is not a date. The items are ordered by dependency, not by schedule, and no date for a hardened mainnet will appear here until the gate above is closed. It is also not exhaustive about internal operational work: the checklist this page derives from tracks infrastructure and process items that are not useful to publish.