Skip to main content

How Gora apps work

A Gora app has one required part and several optional parts.
PartRequired?What it does
Off-chain appYesJS, TS, Python, or WASM code that reads input and returns JSON
ManifestYesDescribes the app id, runtime artifact, capabilities, and contracts
PolicyYesDefines allowed actions, chains, limits, and payment rules
HTML UIOptionalHTML/CSS/JS loaded by the mobile wallet in a WebView
App interfaceOptionalDeclares app views, actions, chain queries, and transaction shapes for the HTML UI and bridge clients
Chain contract/programOptionalVerifies proofs, stores state, or executes on-chain effects
Mobile approval/signingOptionalLets 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.
Input → Gora runs your app → app returns JSON → Gora signs/records result → wallet or contract acts
Example app result:
{
  "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:
gora devnet up
Local developers point their CLI at the public Gora endpoint:
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:
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 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.
  • 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.

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:
{
  "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:
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

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:
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.