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

# How Gora apps work

> The mental model for apps, Devnet, contracts, attestations, mobile approval, and chain execution.

# How Gora apps work

A Gora app has one required part and several optional parts.

| Part                    | Required? | What it does                                                                                          |
| ----------------------- | --------- | ----------------------------------------------------------------------------------------------------- |
| Off-chain app           | Yes       | JS, TS, Python, or WASM code that reads input and returns JSON                                        |
| Manifest                | Yes       | Describes the app id, runtime artifact, capabilities, and contracts                                   |
| Policy                  | Yes       | Defines allowed actions, chains, limits, and payment rules                                            |
| HTML UI                 | Optional  | HTML/CSS/JS loaded by the mobile wallet in a WebView                                                  |
| App interface           | Optional  | Declares app views, actions, chain queries, and transaction shapes for the HTML UI and bridge clients |
| Chain contract/program  | Optional  | Verifies proofs, stores state, or executes on-chain effects                                           |
| Mobile approval/signing | Optional  | Lets a user review and sign an action or native transaction                                           |

## The core idea

Your app code makes a decision. It does not move money directly.

```text theme={null}
Input → Gora runs your app → app returns JSON → Gora signs/records result → wallet or contract acts
```

Example app result:

```json theme={null}
{
  "type": "agent_action_intent",
  "schema_version": 1,
  "app_id": "my_agent",
  "chain": "algorand",
  "decision": "transfer",
  "payload": {
    "to": "RECIPIENT",
    "amount": "1000",
    "amount_unit": "microalgos"
  }
}
```

That result is an intent. A gateway, wallet, mobile signing flow, or chain-specific submitter must still execute it.

## What Gora Devnet is

Gora Devnet is the developer network you deploy to while building. In the current local Devnet setup, one VM runs:

* the Gora dev HTTP API
* local Base/Ganache RPC
* local Solana validator
* local Algorand localnet
* ngrok tunnels for remote access
* a contract metadata registry

The VM operator starts it with:

```bash theme={null}
gora devnet up
```

Local developers point their CLI at the public Gora endpoint:

```bash theme={null}
gora config set node.url https://DEVNET-ENDPOINT
```

## What the Gora app package contains

A deployed package includes:

* app id and version
* runtime artifact bytes or source
* manifest JSON
* policy JSON
* optional HTML UI
* optional app interface views and actions
* hashes for reproducibility
* optional contract metadata links

It does not include private keys.

## Contracts are separate from app deployment

`gora deploy` deploys the app package to Gora.

`gora contract deploy` handles chain contract metadata. Depending on the chain and flags, it can:

* deploy from the chain host
* record an already deployed address, program id, or app id
* resolve metadata from `GET /v1/contracts/{chain}` on Gora Devnet

For normal local development against a VM Devnet, prefer:

```bash theme={null}
gora contract deploy --chain algorand --node https://DEVNET-ENDPOINT
```

That records the deployed Algorand `app_id` from Devnet. Your local machine does not need the Algorand VM `--datadir`.

## Attestations

An attestation is Gora's proof that a request was evaluated.

It binds together information such as:

* request id
* app id
* input hash
* output hash
* app/package metadata
* node or validator signature data

Apps and contracts use attestations to prove that the result came from the deployed Gora app, not from an arbitrary client.

The attestation is signed by the committee that evaluated the request. See [Validators and consensus](./validators-and-consensus) for who that committee is, how members are selected, and how a contract on Base, Solana, or Algorand verifies the signatures.

## Randomness and external data

Two capabilities that most apps eventually want:

* **Verifiable randomness.** Each request arrives with a VRF output your app can read from `req.vrf`. Smart contracts can request randomness through the chain gateway and verify the proof on-chain. See [Randomness and VRF](./randomness-and-vrf).
* **External HTTP calls.** Off-chain apps reach allowlisted endpoints through a sandboxed `gora.fetch`. The committee agrees on the response either via a proposer-fetch transcript (cheap and fast) or quorum fetch (every validator hits the endpoint, useful for oracle-grade data). See [External calls](./external-calls).

## Mobile approval and mobile signing

Mobile approval means the user reviewed a pending action and approved or rejected it.

Mobile signing means the user signs a chain payload or native transaction with their wallet key.

Both are optional surfaces. They do not mean Gora holds user keys.

## Mobile UI

The mobile wallet renders app UIs as HTML in a WebView. There is no separate native renderer for app-specific screens.

Apps can declare one of these in `gora.app.json`:

```json theme={null}
{
  "ui": {
    "type": "html",
    "html_path": "ui/index.html",
    "bridge": "gora_webview_v1"
  }
}
```

They can also use `ui.html` for inline HTML or `ui.url` for a hosted app UI.

Inside the WebView, the mobile wallet injects `window.Gora`. The basic bridge methods are:

```js theme={null}
await window.Gora.context()
await window.Gora.view("participants")
await window.Gora.action("register", { chain: "base" })
await window.Gora.invoke({ round: 1, participants: [] })
```

The HTML owns layout and app-specific UX. Native code owns wallet keys, signing, transaction submission, and bridge calls.

## What Gora does not do

Gora does not automatically:

* hold user keys
* sign transactions for users
* pay user gas
* submit every chain transaction
* turn an app intent into chain state without a gateway, wallet, or submitter

## End-to-end flow

```text theme={null}
Developer creates app locally
        ↓
Developer links contract metadata, if needed
        ↓
Developer deploys app package to Gora
        ↓
User/client invokes app
        ↓
Gora runs app and returns result + attestation
        ↓
Mobile, wallet, gateway, or contract executes the approved chain action
```

## App interfaces

An app interface is the app-owned description of how the HTML UI and generic clients should inspect and act on the app. It keeps app-specific chain reads and transaction shapes out of the Gora node, Dev Bridge, and mobile wallet.

For example, an app can declare:

* a `participants` view that reads an EVM indexed getter or Algorand opt-ins
* a `next_round` view that reads per-chain round counters and reduces them with `max`
* a `register` action that maps to an EVM call, Solana instruction, or Algorand app opt-in
* a `settle_winner` action that maps app output fields into chain transaction arguments

Transaction declarations should include the data a generic signer needs:

* EVM selector plus ABI arg paths
* Solana program id, ordered accounts, signer/writable flags, and instruction data bytes
* Algorand app id, `on_complete`, app args, foreign accounts, and minimum fee

Generic clients call:

```text theme={null}
GET /apps/:id/ui
GET /apps/:id/views/:view_id
POST /apps/:id/actions/:action_id/build
```

The app supplies the UI and interface; the bridge serves HTML, evaluates declared chain reads, and returns normalized JSON.

Next: [Create a Gora app](../app/create-offchain-wasm-app).
