Temetro Network
The high-performance relay that connects your clinic to patient wallet apps.
Temetro Network is a small, standalone service that connects your clinic to patients' wallet apps. When a clinic imports a record from a phone, pushes an update, or a patient approves a share, those messages travel through the network.
It is open source and lives in its own repository: github.com/temetro/temetro-network.
Why it exists
Earlier, the clinic backend talked to phones directly and exposed itself to the internet through a temporary tunnel. That tunnel was unreliable — it worked sometimes and not others, and a patient scanning the QR would sometimes see "couldn't reach the clinic."
Temetro Network replaces that tunnel with a dedicated relay at a stable address that is always on. Both your backend and patient phones connect to it, and it routes messages between them.
What it does (and does not) do
The relay is a dumb pipe by design:
- It forwards the encrypted messages between clinics and the right phone.
- It verifies two signatures — that a device controls its wallet, and that a clinic controls its signing key — before routing. This is the only cryptography it performs.
- It is multi-clinic: many self-hosted clinics use the same relay at once, each identified by its own signing key, and the relay routes each patient response back to the one clinic that asked — a clinic never sees another clinic's traffic.
- It never opens sealed record bundles, holds no database, and stores nothing. Only your clinic backend (which holds the ephemeral key) can decrypt a shared record.
Who decides a clinic is legitimate?
The patient does. Every record change is signed by the clinic's key, and the patient approves it on their phone after seeing who it's from. The relay uses a clinic's key only as a routing identity — it never has to vouch for a clinic, so no central authority or registry is involved.
End-to-end encrypted
Records are sealed on the patient's phone and can only be opened by your clinic. The network only ever sees ciphertext, so running it — even on someone else's infrastructure — never exposes patient data.
Deploying your own
The network deploys in minutes on Railway or any container host.
-
Create a new project from the temetro-network repo. It ships a
Dockerfileandrailway.toml, so the platform builds it automatically. The health check isGET /healthz. -
No variables are required.
PORTis injected by the platform, and each clinic authenticates with its own signing key — so an open relay needs no shared secret. (Optional: setRELAY_TOKENto additionally gate a private relay behind a shared token, orRUST_LOGto tune logging.) -
Point your clinic backend at the deployed relay by setting one environment variable (see Self-hosting):
Variable Value RELAY_URLthe relay's public URL (e.g. https://your-relay.up.railway.app) -
Point the wallet app's relay URL at the same public URL.
Once relay, backend, and wallet app share the URL, the whole import and update flow runs on infrastructure you control.
One relay, many clinics
The same relay serves any number of self-hosted clinics at once. Each clinic proves its identity with its own signing key when it connects, and the relay keeps each clinic's traffic separate — so clinics can share a public relay without a shared password.
Joining the network
A clinic joins the network explicitly. In Settings → Signing, turn on Join Temetro Network. Until it's on, this clinic makes no relay connection and the wallet-import and update features are unavailable. Turning it off disconnects the clinic and stops all wallet sharing.
How a share travels the network
patient phone ──▶ Temetro Network ──▶ clinic backend
(wallet app) (the relay) (opens the record)- The clinic sends an encrypted share request; the relay forwards it to the patient's phone.
- The patient approves in their wallet. The app seals the record to the clinic's one-time key and sends it back through the relay.
- The relay hands the sealed bundle to your backend, which opens it and shows the draft record for the clinician to review and commit.
The relay treats every one of those messages as opaque bytes.