Skip to main content

Create a Gora app

A Gora app starts as a local folder. You edit it locally, validate it locally, then deploy it to a Gora endpoint.

Choose a starter template

The fastest path is to use a template:
TemplateUse it when
offchain-callbackYour app returns an off-chain result or callback payload
mobile-coin-flipYou want a small mobile-signing example
agent-mobile-signingYour AI agent prepares user-paid transactions or approvals
Example:
gora init my-agent --template agent-mobile-signing --chain base --yes
cd my-agent
You can override the default language or app shape:
gora init my-agent \
  --language typescript \
  --chain algorand \
  --app-kind ai-agent-wallet \
  --contract true \
  --wallet true \
  --yes
Supported languages:
  • typescript
  • javascript
  • python
  • wasm
Supported app kinds:
  • offchain-only
  • smart-contract-native
  • offchain-program-wallet
  • ai-agent-wallet

Generated files

A TypeScript app looks like this:
my-agent/
  gora.app.json
  policy.json
  package.json
  ui/
    index.html
  src/index.ts
  fixtures/request.json
  fixtures/expected-output.json
  contracts/
  artifacts/
  .gora/
Important files:
FilePurpose
src/index.ts / src/index.js / src/main.pyApp code that Gora runs
gora.app.jsonManifest: id, runtime, capabilities, contract links
policy.jsonAllowed actions, chains, limits, and payment rules
ui/index.htmlOptional mobile UI rendered in the Gora wallet WebView
fixtures/request.jsonLocal request input for testing
.gora/Local receipts, package output, config, and contract metadata

Mobile UI

The mobile wallet renders app-specific UI as HTML only. Add a ui section to gora.app.json:
{
  "ui": {
    "type": "html",
    "html_path": "ui/index.html",
    "bridge": "gora_webview_v1"
  }
}
For very small demos you can use ui.html with inline HTML. For partner-hosted apps you can use ui.url. The WebView injects window.Gora so your HTML can ask native code for wallet context, read declared views, invoke the app, and open the native signer:
const context = await window.Gora.context();
const participants = await window.Gora.view("participants");
await window.Gora.action("register", { chain: context.selected_chain });
Keep private keys, seed phrases, RPC secrets, and algod tokens out of HTML. The HTML is a UI surface; native wallet code still owns signing.

Runtime contract

For JS, TS, and Python apps:
stdin:  JSON request envelope
stdout: JSON result only
stderr: logs
exit 0: success
exit nonzero: failure
Do not print logs to stdout. Stdout is parsed as the app result. Example TypeScript result:
import { readFileSync } from "node:fs";

const input = JSON.parse(readFileSync(0, "utf8"));

console.log(JSON.stringify({
  type: "agent_action_intent",
  schema_version: 1,
  app_id: "my_agent",
  chain: "base",
  decision: "approve_native_transfer",
  reason: `Handled ${input.request_id}`,
  mobile_signing_request: {
    chain: "base",
    kind: "native_transfer",
    from: "user_wallet_address",
    to: "recipient_wallet_address",
    amount: "1000",
    amount_unit: "wei"
  }
}));

Build

gora build
For JS, TS, and Python, this verifies that the manifest-declared artifact exists and is non-empty. For WASM, it builds or verifies artifacts/program.wasm.

Validate

gora validate
Validation checks:
  • manifest and policy JSON
  • app id and package metadata
  • artifact path and runtime kind
  • allowed actions and chains
  • linked contract metadata
  • obvious secret-looking fields

Package

gora package
This writes:
.gora/package/package.json
The package is what gora deploy uploads to Gora.

What not to put in an app

Do not put these in source, manifest, policy, fixtures, package metadata, or stdout:
  • private keys
  • seed phrases
  • deployer keys
  • API tokens
  • RPC secrets
  • Algod tokens
Use environment variables or local dev tooling for secrets. The package should be safe to upload. Next: Add chain contracts.