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

# Project status

> What is built, what is proven, what is stubbed, and what is not started.

Nelo is a hackathon project built against a four-week plan. This page is the honest ledger of where it actually is.

<Note>
  Three states are kept apart, because conflating them is how a demo ends up claiming something untrue:

  * **Proven** — a test that has actually executed, or a run on devnet
  * **Written** — code exists and compiles, but has never run
  * **Declared stub** — deliberately not real, and labelled as such at every call site
</Note>

## Where it stands

<CardGroup cols={2}>
  <Card title="The trust model" icon="shield-check">
    **Proven, on devnet.** Vault, voucher redemption with the signature verified by the precompile on a real validator, 128-slot replay window, timelocked withdrawal, conflict freeze, double-spend refused.

    Caveat: run with a *software* P-256 key, not StrongBox.
  </Card>

  <Card title="The ordinary sale" icon="receipt">
    **Written, and typechecked.** Till, MWA wallet, Solana Pay, payment validation, day-book, balance, SPL collateral, onboarding.

    Caveat: **never rendered.** A dev-client build compiles the native side but does not embed the JS.
  </Card>

  <Card title="Trust Stake" icon="coins">
    **Proven, on devnet.** 17 curve tests off chain, \~19 on chain in LiteSVM, and `RiskConfig` now live on a real validator with `redeem_voucher` exercised against its new account struct.
  </Card>

  <Card title="Settlement" icon="book">
    **Ledger proven** (39 tests) — double-entry, idempotent, reversible, reconcilable. Partner is a **declared stub**.
  </Card>
</CardGroup>

## By component

| Component                           | State                                                               |
| ----------------------------------- | ------------------------------------------------------------------- |
| `programs/nelo_vault` — trust model | ✅ Proven on devnet                                                  |
| `programs/nelo_vault` — Trust Stake | ✅ Proven — LiteSVM, then devnet                                     |
| `packages/voucher`                  | ✅ Proven, both sides, golden vectors (29 tests)                     |
| `packages/pay`                      | ✅ Proven (54 tests)                                                 |
| `packages/ledger`                   | ✅ Proven (13 tests)                                                 |
| `packages/onboard`                  | ✅ Proven (60 tests)                                                 |
| `packages/reserve`                  | ✅ Proven (16 tests)                                                 |
| `services/settle` — ledger          | ✅ Proven (39 tests)                                                 |
| `services/settle` — partner         | 🟡 Declared stub                                                    |
| `packages/attest`                   | ⚠️ Compiles (EAS build); never run on hardware                      |
| `apps/merchant`                     | ⚠️ Typechecks; native side builds; never rendered                   |
| `apps/payer`                        | ⚠️ Probe only — typechecks, never rendered. Real payer UI is week 3 |
| `services/relay`                    | ❌ Stub — one line                                                   |
| Live price feed                     | ❌ Blocked on a product decision                                     |
| Onboarding — the flow's rules       | ✅ Proven (29 of `@nelo/onboard`'s 60)                               |
| Onboarding — the Privy calls        | ⚠️ Typechecked against the SDK; needs an app ID and a device        |
| Gasless relayer                     | ❌ Not started                                                       |
| Slashing                            | ❌ Not started                                                       |
| CI                                  | ✅ Three jobs — tests, typecheck, `anchor test`                      |

## The three things that block the most

<Steps>
  <Step title="Run the app on a handset">
    The one that blocks the most, now that the chain side is settled. The native build compiles, but a development client loads its JS from Metro — so **nothing in either app has rendered**. Every screen, every state transition and every native call is unverified at runtime.

    It answers three questions at once: does the JS bundle, does StrongBox behave on real hardware, and does MWA find a wallet.
  </Step>

  <Step title="Get a Privy app ID">
    Onboarding's done-when is *setup completed without ever seeing a key*, and it cannot be demonstrated without one. The flow's rules are tested; the SDK calls are typechecked and unexecuted. A build with no app ID runs and simply does not offer the phone route.
  </Step>

  <Step title="Settle the payout partner">
    No licensed partner has been signed. The ledger is real and the stub is honest, so the fork is cheap — but the real leg cannot be built against an API nobody has access to.
  </Step>
</Steps>

## Decisions waiting on a person

<AccordionGroup>
  <Accordion title="Which launch currency, or which oracle" icon="money-bill-transfer">
    Pyth publishes **no NGN feed** — 39 FX pairs, and the naira is not among them. Of the markets the plan names, Manila (PHP) is covered; Lagos is not.

    Either pick a covered launch currency, or source NGN from Switchboard or a commercial feed. Hermes also requires an API key for prices. Until one is settled, the till runs a configured rate and says so on screen.
  </Accordion>

  <Accordion title="The reserve line, and the premium claim" icon="calculator">
    [The reserve model](/economics/reserve-model) finds the 0.20% insurance line does not cover expected loss — 28.1 bps implied — and that reserve relief funds a premium of \~1.001×, not the illustrative 1.5×.

    Both are changes to documents and one constant, not to the architecture. Both should be settled before the deck goes out.
  </Accordion>

  <Accordion title="k and the hard cap, together" icon="sliders">
    The curve raises required reserve below \~$250 of staked value, and the $500 hard cap needs \$81,000 of stake to bind. Neither parameter can be fixed without the other.

    Both are `RiskConfig` updates rather than redeploys.
  </Accordion>

  <Accordion title="Whether to widen the conflict proof" icon="scale-unbalanced">
    `report_conflict` only freezes on two vouchers at the **same** sequence. Successive sequences with inconsistent `remaining_after` do not trigger it, and that residual is what the insurance line prices.

    Accepting that pair as proof would shorten the window a compromised device keeps trading in. It changes the fraud model, so it is flagged rather than taken.
  </Accordion>
</AccordionGroup>

## What is deliberately not built

Named rather than discovered, because a named stub reads as confidence and a discovered one reads as spin:

* **Slashing.** The freeze blocks the exit, so stake cannot walk away from a loss it backs — but nothing yet *moves* it to a reserve, because there is no reserve account. That is the other half of "first-loss capital".
* **The payout partner adapter.** The interface exists; the implementation waits on sandbox access.
* **An HTTP surface on `settle`.** It is a library the relay and the app will call, not a server.
* **Embedded-wallet recovery.** `needs-recovery` is detected and reported; `useRecoverEmbeddedWallet` is not wired, so the retry on that screen will not clear it. It arises when a wallet has to be reconstructed on a new device, which is exactly the case a merchant who changes phones hits — so it is a gap with a date on it, not a permanent omission.
* **The offline transport.** QR and NFC, cached enrolment and revocation lists, the offline queue — all week-3 work.
