Skip to main content

Add chain contracts

A Gora app can be off-chain only, but many apps also need a chain contract, gateway, program, or smart wallet. Use a chain contract when you need to:
  • verify a Gora result or attestation on-chain
  • hold app state
  • execute transfers or callbacks
  • enforce replay protection
  • connect mobile/user signatures to chain execution

Key rule

gora deploy deploys your Gora app package. It does not deploy Base contracts, Solana programs, or Algorand applications. Use gora contract ... for chain contract metadata:
gora contract build --chain <chain>
gora contract deploy --chain <chain> --node https://DEVNET-ENDPOINT
gora contract link --chain <chain>
Then deploy the app package:
gora deploy

Local developer vs Devnet operator

If you are developing from your local computer, prefer --node:
gora contract deploy --chain algorand --node https://DEVNET-ENDPOINT
This asks the Gora Devnet endpoint for already deployed chain metadata and records it locally. If you are the Devnet operator on the VM, you may deploy directly using local chain files and tools, such as Algorand --datadir.

Contract metadata endpoint

Gora Devnet exposes chain metadata at:
curl https://DEVNET-ENDPOINT/v1/contracts
curl https://DEVNET-ENDPOINT/v1/contracts/algorand
curl https://DEVNET-ENDPOINT/v1/contracts/base
curl https://DEVNET-ENDPOINT/v1/contracts/solana
Example Algorand response:
{
  "ok": true,
  "chain": "algorand",
  "contract": {
    "chain": "algorand",
    "kind": "algorand_application",
    "name": "GoraAlgorandGateway",
    "role": "app_contract",
    "status": "deployed",
    "app_id": "1001",
    "address": "1001",
    "deployment_tx": "TX_ID",
    "network": "devnet-local",
    "chain_id": "31337",
    "rpc_url": "https://algorand-dev.ngrok.app",
    "auth": {
      "type": "algod_token",
      "header": "X-Algo-API-Token",
      "token_env": "ALGORAND_ALGOD_TOKEN",
      "token_included": false
    }
  }
}
The CLI uses the same endpoint when you run gora contract deploy --node ....

Diagnose setup

Run doctor before deploying:
gora contract doctor --chain algorand --node https://DEVNET-ENDPOINT
Doctor checks local source/build/deploy receipts and remote contract metadata when a node URL is provided.

Base/EVM

Build metadata:
gora contract build --chain base
Resolve the Devnet gateway or contract address:
gora contract deploy --chain base --node https://DEVNET-ENDPOINT
Or record a known address manually:
gora contract deploy \
  --chain base \
  --rpc https://base-dev.ngrok.app \
  --address 0x0000000000000000000000000000000000000000 \
  --deployment-tx 0xTX
Link it into the manifest:
gora contract link --chain base

Solana

Build metadata and default source scaffold:
gora contract build --chain solana
Resolve the Devnet program id:
gora contract deploy --chain solana --node https://DEVNET-ENDPOINT
Or record a known program id:
gora contract deploy \
  --chain solana \
  --rpc https://solana-dev.ngrok.app \
  --program-id Gora111111111111111111111111111111111111111 \
  --deployment-tx EXISTING_SIGNATURE
Link it:
gora contract link --chain solana

Algorand

Build gateway TEAL metadata:
gora contract build --chain algorand
Normal local developer flow:
gora contract deploy --chain algorand --node https://DEVNET-ENDPOINT
gora contract link --chain algorand
This records the deployed Algorand app_id from Gora Devnet. VM/operator direct deploy flow:
gora contract deploy \
  --chain algorand \
  --rpc https://algorand-dev.ngrok.app \
  --datadir /path/to/algorand-localnet/Node
--datadir must point to a local Algorand Node/ directory containing algod.net and algod.token. It only works on the machine running that Algorand localnet. Manual record-existing flow:
gora contract deploy \
  --chain algorand \
  --rpc https://algorand-dev.ngrok.app \
  --app-id 1001 \
  --deployment-tx EXISTING_TX_ID

What linking writes

gora contract link --chain <chain> updates gora.app.json with a contract binding similar to:
{
  "chain": "algorand",
  "kind": "algorand_application",
  "name": "GoraAlgorandGateway",
  "address": "1001",
  "deployment_tx": "TX_ID",
  "chain_id": "31337",
  "network": "devnet-local",
  "role": "app_contract"
}
After linking, run:
gora validate
gora deploy

Custom fulfillment contracts

For custom EVM contracts, prefer a gateway-mediated callback. The custom contract should accept calls only from the trusted Gora gateway and reject duplicate request ids. Minimal interface:
interface IGoraFulfillmentReceiver {
    function fulfillGoraRequest(
        bytes32 requestIdHash,
        bytes32 appIdHash,
        bytes32 outputHash,
        bytes32 attestationHash,
        bytes calldata result,
        bytes calldata proof
    ) external;
}
Your contract should verify:
  • caller is the trusted gateway
  • request id was not already fulfilled
  • app id matches your app
  • output hash matches the supplied result
  • proof/attestation was accepted by the gateway
  • decoded result satisfies your policy limits
Next: Set policy and payments.