Skip to content

Smart Host — the BaaS runtime tier

If the validator is the chain runtime, Smart Host is the Backend-as-a-Service built on top of it. It’s the tier most application developers actually talk to: sign in with a wallet, store some data, run a function, send a message — all of it backed by the validators and, through them, the chains underneath, without making you deal with raw blockchain plumbing.


We could have built this into the validator. We didn’t, for three reasons:

Different audiences

The validator’s API is for advanced users (operators, custodians, sovereignty-aware customers). The host’s API is for application developers who just want a backend.

Different security boundaries

The host holds no chain keys, so it can grow and serve many apps without spreading key material any further.

Different scaling profile

The validator is heavy; the host is fan-out and light. Decoupling lets each scale independently.

The host holds no chain keys and signs nothing on chain. To check a wallet signature, or to get anything done on chain, it calls the validator over HTTP.


%%{init: {'flowchart':{'htmlLabels':true,'curve':'basis'}}}%%
flowchart LR
    Dev([App developer]) --> Host["Smart Host"]
    Host --> Auth["Auth<br/>wallet sign-in · subscription NFT check"]
    Host --> DB["Database + files<br/>Merkle proofs · encrypted storage"]
    Host --> Fn["Functions<br/>sandboxed serverless"]
    Host --> Msg["Messaging<br/>channels · real-time stream"]
    Auth -.->|verify signature| V["Smart Validator"]
    DB -.->|epoch roots signed| V

Wallet-based: you prove you control an address by signing a one-time challenge. There are two sign-in flows, one for the app’s owner and one for the app’s customers.

  1. The app’s owner calls POST /api/v3/baas/auth/challenge with { chain, walletAddress, appId }. The host returns a challengeId, the message to sign, and when it expires.
  2. The owner signs message with the wallet for walletAddress.
  3. The owner calls POST /api/v3/baas/auth/verify with { challengeId, signature } (plus publicKey where the chain needs it). The host asks the validator to check the signature.
  4. The host issues a bearer session token only if the signature is valid, the wallet owns the app, and the app has an active subscription.

An app’s customers sign in the same way through POST /api/v3/baas/customer-session/challenge and POST /api/v3/baas/customer-session/verify, and get a short-lived bearer token (15 minutes at most). If the app sells subscriptions, the host checks at sign-in whether the customer holds the app’s subscription NFT and records its tier on the session.

Sessions are kept by the host and shared with the other clusters, so a token works wherever the next request lands, and it can be ended before it expires.


Pillar 2 — Database (verifiable, not “trust us”)

Section titled “Pillar 2 — Database (verifiable, not “trust us”)”

Each app gets its own document database, with collections you create and query over HTTP. What makes it different is that every write is recorded in a Merkle tree.

  • Every write returns a proof. An insert, update or delete returns a state transition: the new state root and a Merkle proof for the document. You can also fetch a document’s proof at any time with GET /api/v3/baas/db/:appId/:collection/:documentId/proof.
  • Validators sign the roots. Writes are grouped into epochs. When an epoch closes, the validators sign its Merkle root with a post-quantum signature (ML-DSA), and the host keeps the first signature it receives. A validator signs only one root for a host’s epoch, so a host can’t get the same validator to sign two different histories.
  • Anchoring on Hedera is next. Publishing each epoch root to a Hedera topic, so anyone can check a root against the public ledger, is built but not yet enabled.
  • Every cluster gets the write. Writes replicate between hosts. Concurrent writes to the same document are ordered with vector clocks, and the latest write wins.
  • Customer records stay with the customer. When an app forwards its customer’s session, the records that customer creates are bound to them, and other customers can’t read them.

Files work alongside the database. Each uploaded file is encrypted with its own AES-256-GCM key and stored in the validators’ private object store. Files are not put on IPFS.

%%{init: {'flowchart':{'htmlLabels':true,'curve':'basis'}}}%%
flowchart LR
    Val["document"] --> Leaf["leaf hash"]
    Leaf --> Mid["intermediate hashes"]
    Mid --> Root["epoch root"]
    Root --> Signed["signed by a validator (ML-DSA)"]
    Root -.-> Chain[("Hedera anchor<br/>not yet enabled")]

Sandboxed serverless execution. You deploy a function to the host, and the host runs it in its own isolated V8 sandbox with a memory limit and a timeout. The code is screened before it runs, and its outbound fetch can reach only the app’s own host and the hosts the app declared.

Functions can be triggered by:

HTTP

Called like any API.

Schedule

Runs on a schedule, once for each of the app’s customers who opted in.

Data events

A database insert, update or delete, or a file upload or delete, fires the function.

See Host Functions for the full programming model.


Real-time pub/sub on named channels. You publish with POST /api/v3/baas/messaging/:appId/channels/:channel/publish. To receive, you get a single-use ticket from .../subscribe-ticket and open the channel’s stream at .../subscribe?ticket=, which delivers messages as Server-Sent Events. Channels also keep history and presence. Messages reach subscribers on every cluster, and the same session token as the REST side authorises both.


Every request to the host passes the same checks: the session token is verified, the request is rate-limited by the app’s subscription tier, and its usage is metered. The metered usage is charged to the app’s subscription in HSUITE. Hosts also announce themselves to the gateways, so traffic can find them (see Smart Gateway).


%%{init: {'sequence':{'showSequenceNumbers':false}}}%%
sequenceDiagram
    autonumber
    participant Cl as Client (session token)
    participant GW as Smart Gateway
    participant H as Smart Host
    participant P as Other hosts
    participant V as Smart Validators
    Cl->>GW: HTTPS insert
    GW->>H: forward
    H->>H: check session
    H->>H: rate limit (subscription tier)
    H->>H: write document, update Merkle tree
    H-->>Cl: state transition + Merkle proof
    H->>P: replicate the write
    H->>V: epoch closes, request root signatures
    V-->>H: ML-DSA signature over the epoch root

The host keeps your data and its proofs; a validator vouches for each epoch root.


  • Smart Host is the BaaS tier — sign-in, database, files, functions, messaging — built on top of the validator, with no chain keys of its own.
  • Sign-in is wallet-based, with a bearer session token, and can check an app’s subscription NFT.
  • The database records every write in a Merkle tree, returns proofs, and has its epoch roots signed by a validator. Anchoring the roots on Hedera is built but not yet enabled.
  • Files are encrypted per file and kept in the validators’ private object store.
  • Functions run sandboxed and can be triggered by HTTP, a schedule, or data events.
  • Messaging is real-time pub/sub over Server-Sent Events.
  • Usage is metered and charged to the app’s subscription.