Skip to main content

How Gora apps work

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

The core idea

Your app code makes a decision. It does not move money directly.
Example app result:
That result is an intent. A gateway, wallet, mobile signing flow, or chain-specific submitter must still execute it.

Two runtimes, different superpowers

In practice: WASM apps read their input, keep durable state, and can call an LLM — that is how agents are built on Gora, and WASM is what the WASM-only public testnet runs. JS / TS / Python run unsandboxed and are for a self-hosted node only. Exact ABI, host function signatures, and limits: WASM runtime reference.

What you deploy to

The public Gora testnet is the network you deploy to while building. The bridge serves the public API; hosted UIs receive separate app-specific HTTPS origins. You can also host the UI on your own website. Point your CLI at the API:
Algorand gateway/vault callbacks and Base/Solana managed agent signing are live testnet paths. All three chains also support validator staking. Base/Solana managed agents call your own contracts/programs; they do not require the separate, undeployed Gora gateways. See Connect to the testnet. An operator can also run the whole stack locally — Gora HTTP API, local Base/Ganache RPC, local Solana validator, Algorand localnet, and a contract metadata registry — with:

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 a Gora node
For normal development against the public testnet, prefer:
That records the deployed managed Algorand gateway 771952005. Your local machine does not need an Algorand --datadir. The legacy gateway 767488273 is a separate path; do not substitute it for managed settlement.

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. See Validators and consensus for the managed replay signatures and their limits. On-chain consumers do not automatically verify every vote: the current Algorand gateway uses an operator settlement signer, while Base/Solana managed signers enforce the separately approved agent policy. Verify execution, delivery and chain state independently.

Randomness and external data

Two capabilities that most apps eventually want:
  • Verifiable randomness. The repository has a separate legacy/target VRF protocol. The current managed WASM request ABI does not automatically supply req.vrf; caller-provided randomness is not a verified VRF result. See the scope warning in Randomness and VRF.
  • External HTTP calls. WASM uses gora::http_get for allowed hosts. Managed validators replay captured responses; they do not independently fetch and vote on source truth. 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. Approvals are cryptographically verified, not trusted: the wallet signs a canonical approval document with the user’s per-chain key, and the receiving side re-verifies the signature against the signer’s address (EVM personal_sign recovery; ed25519 for Solana and Algorand). A forged or tampered approval is rejected before anything executes. See Web UI and verified signing. Both are optional surfaces. The owner wallet key stays local. A separately approved managed agent key is held on the VM, under its own bounded policy.

Mobile UI

The mobile wallet renders app UIs as HTML in a WebView. There is no separate native renderer for app-specific screens. For a multi-screen frontend, build static assets and declare their directory in gora.app.json:
The CLI packages the files and their digests. The current limits are 256 assets, 2 MiB base64-encoded per asset and 8 MiB encoded in total. Do not package keys, tokens or private journals. Keep large images/videos on HTTPS CDNs. SPA fallback serves the entry for extensionless client routes; native bridge privileges remain scoped to the selected app and approved origin. A single-file UI can instead use:
gora deploy embeds that file as ui.html (up to 1 MiB) so the bridge can serve it wherever the app was deployed from. Apps can also write ui.html inline or use ui.url for a hosted app UI. Inside the WebView, the mobile wallet injects window.Gora. The basic bridge methods are:
action() opens the native sign pop-up; the outcome comes back as DOM events (gora:actionComplete with the verified approval proof, gora:actionCancelled on decline, gora:actionFailed on execution errors). Full API: Web UI and verified signing. 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

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:
The app supplies the UI and interface; the bridge serves HTML, evaluates declared chain reads, and returns normalized JSON. Next: Create a Gora app.