> ## Documentation Index
> Fetch the complete documentation index at: https://veriqa.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Nova Stream — streaming on a TV

> A showcase sample that imitates a streaming service on a television: sign-in by QR code from the sofa, the viewer's card from channel claims, and step-up when buying a title.

Nova Stream is a runnable emulator of a **product**, not of one mechanism. The scenario samples each
show a single thing — a sign-in, a confirmation, a step-up; this one strings them together the way a
viewer encounters them on a television: a sign-in, the person's data, recognition on the next visit and a
confirmed purchase.

The sample lives in the repository ([veriqa.app/source](https://veriqa.app/source)) under
`samples/dotnet/showcase/streaming-tv` and listens on `https://localhost:7350`. Its `README.md` is
the detailed setup guide; this page is the overview.

## What the viewer sees

<Steps>
  <Step title="Sign-in by QR code from the sofa">
    The TV redirects to the Veriqa sign-in page, which shows a QR code. The viewer scans it with their
    phone camera and confirms in the messenger — nothing is typed with the remote.
  </Step>

  <Step title="A welcome card from the channel's claims">
    The card on screen is built from what the channel provides: display name, first and last name,
    picture, `@username` and a masked user id (Telegram), a masked phone (WhatsApp), an address
    (Email) — Nova Stream asks for the contacts at sign-in. Identifiers are masked on the server; the
    full value never reaches the browser.
  </Step>

  <Step title="A date of birth and a favorite genre inside the sign-in">
    The `Veriqa:ScopesClaims` catalog declares both, so Veriqa asks for them on its own form inside
    the sign-in, and the collected claims store remembers the answer. 18+ titles are closed to a
    viewer under age, and titles of the favorite genre come first. See
    [Progressive claim enrichment](/docs/concepts/claim-enrichment).
  </Step>

  <Step title="Recognition of a returning viewer">
    A first-time viewer is welcomed by name; a viewer who has been here before lands straight in
    the catalog.
  </Step>

  <Step title="Step-up when buying a title">
    Buying a title shows a QR code and is confirmed in the channel **by the viewer who asked**. A
    confirmation from anybody else buys nothing.
  </Step>
</Steps>

The two flows leave different receipts in the chat. A sign-in's question is replaced by "Sign-in to
Nova Stream confirmed ✅" (`ReplacePrompt`); a purchase keeps its question and gets the receipt as a
message of its own (`NewMessage`, set in the backend client's entry), so what was confirmed stays
readable. See `OutcomeNotice` in [Configuration](/docs/reference/configuration).

### The interface on a television

The interface belongs to the fictional service: a ten-foot layout, remote-control navigation and no
interaction that needs a pointer.

| Key | What it does |
| - | - |
| arrows | move the focus |
| `Enter` | select |
| `Backspace`, Tizen `10009`, webOS `461` | close the purchase window |
| `F` (desktop) | full screen |

The sign-in page and the confirmation window are Veriqa's own screens, shown as they are: the sample
names its brand beside the Veriqa mark and adapts the arrangement for a big screen through
`AuthPageDesign`:

* the television shows the QR codes of all enabled channels side by side — the
  [channel layout](/docs/guides/customization#channel-layout) is `Grid`, because nobody walks up to a TV
  to switch a tab;
* the "Open in …" buttons appear on a phone only — the
  [visibility of the channel buttons](/docs/guides/customization#channel-button-visibility) is
  `MobileOnly`; a phone that opens the page gets the buttons instead of the QR;
* the QR of the purchase window is drawn at 12 px per module instead of the default 6, so it scans
  off the screen from across the room;
* a stylesheet enlarges the card on screens 1600 CSS pixels wide or wider.

**A set of channels per browser language.** The sign-in client has two `ui_config` records that
differ in `Channels`; the sample names one of them in the authorize request by the first language of
`Accept-Language`. A record narrows what the host has enabled — it is presentation, not a
restriction.

### TV browsers

Everything the page ships targets **ES2018** and the CSS of Chromium 68 — the engine of Tizen 5.5 and
webOS 5 — with fallbacks for the Chromium 53 of webOS 4.x where a layout depends on it. Newer syntax
such as `?.` or `??` is a parse error there: the script does not load at all. Nothing is loaded from
outside the origin.

## How it is built

One process plays three roles; splitting them into separate hosts changes nothing but the addresses.

| Role | What it is |
| - | - |
| Embedded issuer | Veriqa inside the process: `AddVeriqaAuthServer` → `UseVeriqaAuthServer` → `MapVeriqaAuthServer` |
| Browser-side OIDC client | the standard `AddOpenIdConnect` handler, pointed at this very process |
| Backend that creates confirmations | `VeriqaConfirmationClient`, calling the [server-to-server confirmation API](/docs/reference/confirmation-api) over HTTP |

The purchase creates a confirmation that names **one** expected identity — the identity from the channel the
current session came through (`expected_identities`). The title is bought only when the outcome is
`confirmed` and `matched_type` is the expected type; another type, `declined`, `expired` or
`failed` leave the library unchanged. The server remembers which title a transaction pays for, so no browser can buy one title by confirming another.

## Running it

* .NET SDK 10.0+ and a trusted development certificate (`dotnet dev-certs https --trust`) — the
  application calls itself over HTTPS.
* **Enable at least one channel and give it credentials.** Channels ship disabled with empty
  credentials; a Telegram bot token is the shortest path:

```bash theme={null}
dotnet user-secrets --project samples/dotnet/showcase/streaming-tv set "Veriqa:Channels:Telegram:BotToken" "<token>"
dotnet user-secrets --project samples/dotnet/showcase/streaming-tv set "Veriqa:Channels:Telegram:Enabled" "true"
dotnet run --project samples/dotnet/showcase/streaming-tv
```

Open `https://localhost:7350`. WhatsApp and Email are switched on the same way, through their
sections of `appsettings.json`. A sign-in page that offers no way in means no channel is enabled.

<Note>
  In `Development` the sample switches WhatsApp and Email on with placeholder values, only to show
  what a multi-channel sign-in page looks like. Neither can carry a sign-in through — Telegram is the
  channel that works.
</Note>

**On a real TV.** A television cannot reach `localhost`: put the sample behind an HTTP tunnel. Nothing
in the code changes — the issuer, the redirect URI, the authority and the channels' public addresses
are set to the public host through environment variables, all of them together, and Telegram
switches to `Webhook` mode. The exact list is in the sample's README; see also
[Behind a reverse proxy](/docs/guides/reverse-proxy).

<Tip>
  A Telegram bot delivers its updates to one webhook address, so with one bot token only one of the
  two showcase samples can take sign-ins at a time.
</Tip>

## Videos

<CardGroup cols={2}>
  <Card title="Sign-in on a TV" icon="tv" href="/docs/videos/tv-sign-in">
    Sign-in by QR code from the sofa on a real TV, with no keyboard and no typing.
  </Card>

  <Card title="Step-up on a TV" icon="cart-shopping" href="/docs/videos/tv-step-up">
    Buying a title, confirmed in the messenger by the signed-in viewer.
  </Card>
</CardGroup>

## See also

* [Samples](/docs/samples#showcase-samples)
* [Sign-in surfaces](/docs/scenarios/surfaces)
* [Smart TV and keyboard-free surfaces](/docs/research/smart-tv)
* [Second factor, step-up and action approvals](/docs/scenarios/step-up)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.