> For the complete documentation index, see [llms.txt](https://docs.ethosis.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ethosis.org/architecture/platform.md).

# The web platform

Ethosis ships a reference front-end and relayer as one application, the platform, served at `/platform` on the main site. It is built with Next.js, uses Privy for authentication, and keeps the shared order book in Supabase. No figure on the platform is hardcoded: markets, prices, parameters, requests, offers, loans and events all come out of Supabase.

## Routes

| Route                 | Who can use it              | Contents                                                                                                                                                                                                |
| --------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/platform`           | Anyone                      | Protocol statistics, the market table with tier limits and live indicative rates, and the open requests                                                                                                 |
| `/platform/borrow`    | Signed-in users             | A form to create a borrow request (collateral, principal, maximum APR, term, deadline) with live LTV, health factor and fee; the user's own requests with their fill coverage from the book; settlement |
| `/platform/lend`      | Anyone; more when signed in | The public book of open requests; posting standing or targeted offers with flags; the user's own offers with remaining capacity and a cancel action                                                     |
| `/platform/positions` | Signed-in users             | Loans the user has taken (debt, accrued interest, health, repay, top up) and the slices the user holds                                                                                                  |
| `/platform/explorer`  | Anyone                      | The loan registry with each syndicate and its events, concentration by token measured against the caps, and the parameters in force                                                                     |
| `/platform/settings`  | Signed-in users             | The user's profile and the eligibility attestations issued to their wallet                                                                                                                              |

## Sign-in and the Privy to Supabase bridge

Privy handles sign-in, by email, Google or any EVM wallet. A user who arrives without a wallet is given an embedded one on Robinhood Chain, and that address becomes the signer for their requests and offers.

Supabase has no built-in understanding of Privy, so the platform joins them on the server side:

1. Public data (markets, prices, parameters, the order book, loans, slices, events) is fetched directly from the browser using the anon key.
2. Any operation performed as a user (reading the profile or attestations, posting requests and offers, cancelling, settling, repaying, topping up) goes to `POST /api/platform/db` with the Privy access token attached.
3. That route checks the token with `@privy-io/server-auth`, validates the arguments, and executes the operation through a service-role Supabase client that passes the verified user id in an `x-ethosis-actor` header. The database function `app_user_id()` honours that header only on service-role requests, so the ownership checks inside the `security definer` functions run against the genuine user.

The service-role key stays on the server at all times. Row-level security continues to limit what the anon key can read, and every write continues to pass through the database functions that enforce the matching rules.

## Database schema

`supabase/schema.sql` defines the schema, which follows the on-chain design table for table:

| Table                            | On-chain counterpart                                        | Written by                          |
| -------------------------------- | ----------------------------------------------------------- | ----------------------------------- |
| `markets`                        | Token and tier configuration in `PolicyController`          | Service role                        |
| `oracle_prices`                  | `PriceGate.quote()`                                         | Service role (a keeper or cron job) |
| `protocol_params`                | `PolicyController` parameters plus the deployment addresses | Service role                        |
| `attestations`                   | `AttestationStore`                                          | Service role (the KYC issuer)       |
| `borrow_requests`                | The relayer's book of requests                              | Borrowers, via the API route        |
| `offers`                         | The relayer's book of offers (signed EIP-712 messages)      | Lenders, via the API route          |
| `loans`, `slices`, `loan_events` | `LoanDesk` state                                            | Database functions only             |

Every state transition is a `security definer` function (`settle_request`, `cancel_request`, `cancel_offer`, `record_repayment`, `record_collateral_added`). This is how the matching rules (term, APR ceiling, tier scope, capacity, minimum fill, expiry, full coverage) are applied in the database in exactly the way `LoanDesk` applies them on-chain.

## Typed-data signing

Requests and offers are signed as EIP-712 typed data whose struct layout and domain (`Ethosis` / `1` / chain id / `LoanDesk`) match `contracts/src/libraries/IntentHash.sol`. The typed-data hash is saved next to the signature so that a relayer, or the contract itself, can verify it afterwards. Privy's `signTypedData` makes signing free of gas.

## Two ways to settle

Contract addresses live in the `deployment` row of `protocol_params`. If `LoanDesk` is present there, settling a request sends a genuine `originate` transaction from the user's Privy wallet (using viem's `writeContract`) and stores the transaction hash on the loan. If it is absent, settlement is recorded in the book alone and the loan is labelled to say so. Matching is greedy by APR, in the same order the relayer documentation describes.

## Look and feel

To read as a single product with the marketing site, the platform reuses its design tokens: the `ethos-*` colours, the Space Grotesk, Inter and JetBrains Mono typefaces, and the `.panel` and `.btn` primitives. On desktop it is a sidebar shell; on phones the sidebar becomes a drawer.

## Configuration

Setup instructions are in `supabase/README.md` and `.env.example` at the root of the repository. If any environment variable is missing, the platform shows a setup notice naming it instead of failing quietly.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ethosis.org/architecture/platform.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
