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

# Add chain contracts

> Build, resolve, link, and diagnose Base, Solana, and Algorand contract metadata for a Gora app.

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

```bash theme={null}
gora contract build --chain <chain>
gora contract deploy --chain <chain> --node https://DEVNET-ENDPOINT
gora contract link --chain <chain>
```

Then deploy the app package:

```bash theme={null}
gora deploy
```

## Local developer vs Devnet operator

If you are developing from your local computer, prefer `--node`:

```bash theme={null}
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:

```bash theme={null}
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:

```json theme={null}
{
  "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:

```bash theme={null}
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:

```bash theme={null}
gora contract build --chain base
```

Resolve the Devnet gateway or contract address:

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

Or record a known address manually:

```bash theme={null}
gora contract deploy \
  --chain base \
  --rpc https://base-dev.ngrok.app \
  --address 0x0000000000000000000000000000000000000000 \
  --deployment-tx 0xTX
```

Link it into the manifest:

```bash theme={null}
gora contract link --chain base
```

## Solana

Build metadata and default source scaffold:

```bash theme={null}
gora contract build --chain solana
```

Resolve the Devnet program id:

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

Or record a known program id:

```bash theme={null}
gora contract deploy \
  --chain solana \
  --rpc https://solana-dev.ngrok.app \
  --program-id Gora111111111111111111111111111111111111111 \
  --deployment-tx EXISTING_SIGNATURE
```

Link it:

```bash theme={null}
gora contract link --chain solana
```

## Algorand

Build gateway TEAL metadata:

```bash theme={null}
gora contract build --chain algorand
```

Normal local developer flow:

```bash theme={null}
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:

```bash theme={null}
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:

```bash theme={null}
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:

```json theme={null}
{
  "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:

```bash theme={null}
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:

```solidity theme={null}
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](./set-policy-and-payments).
