Back to skills
SkillHub ClubResearch & OpsFull StackTesting

aavegotchi-gotchiverse

Operate Aavegotchi Gotchiverse player workflows on Base mainnet (8453): alchemica channeling, surveying and harvesting, crafting installations/tiles, building on parcels (equip/unequip/move/batch equip), installation upgrades, craft/upgrade queue management, and parcel access-right management. Use when interacting with Realm/Installation/Tile diamonds via subgraph-first discovery and onchain verification/execution with Foundry cast.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,129
Hot score
99
Updated
March 20, 2026
Overall rating
C0.0
Composite score
0.0
Best-practice grade
B71.9

Install command

npx @skill-hub/cli install openclaw-skills-aavegotchi-gotchiverse

Repository

openclaw/skills

Skill path: skills/cinnabarhorse/aavegotchi-gotchiverse

Operate Aavegotchi Gotchiverse player workflows on Base mainnet (8453): alchemica channeling, surveying and harvesting, crafting installations/tiles, building on parcels (equip/unequip/move/batch equip), installation upgrades, craft/upgrade queue management, and parcel access-right management. Use when interacting with Realm/Installation/Tile diamonds via subgraph-first discovery and onchain verification/execution with Foundry cast.

Open repository

Best for

Primary workflow: Research & Ops.

Technical facets: Full Stack, Testing.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install aavegotchi-gotchiverse into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding aavegotchi-gotchiverse to shared team environments
  • Use aavegotchi-gotchiverse for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: aavegotchi-gotchiverse
description: >
  Operate Aavegotchi Gotchiverse player workflows on Base mainnet (8453):
  alchemica channeling, surveying and harvesting, crafting installations/tiles,
  building on parcels (equip/unequip/move/batch equip), installation upgrades,
  craft/upgrade queue management, and parcel access-right management.
  Use when interacting with Realm/Installation/Tile diamonds via subgraph-first
  discovery and onchain verification/execution with Foundry cast.
metadata:
  openclaw:
    requires:
      bins:
        - cast
        - curl
        - python3
      env:
        - FROM_ADDRESS
        - PRIVATE_KEY
        - BASE_MAINNET_RPC
        - DRY_RUN
        - REALM_DIAMOND
        - INSTALLATION_DIAMOND
        - TILE_DIAMOND
        - AAVEGOTCHI_DIAMOND
        - FUD
        - FOMO
        - ALPHA
        - KEK
        - GLTR
        - GOTCHIVERSE_SUBGRAPH_URL
        - CORE_SUBGRAPH_URL
        - GOLDSKY_API_KEY
    primaryEnv: PRIVATE_KEY
---

## Safety Rules

- Default to `DRY_RUN=1`. Never broadcast unless explicitly instructed.
- Always verify Base mainnet before any action:
  - `~/.foundry/bin/cast chain-id --rpc-url "${BASE_MAINNET_RPC:-https://mainnet.base.org}"` must be `8453`.
- Always verify key/address alignment before any broadcast:
  - `~/.foundry/bin/cast wallet address --private-key "$PRIVATE_KEY"` must equal `FROM_ADDRESS`.
- Always refetch from subgraph immediately before state-changing simulate/broadcast steps.
- Always revalidate critical values onchain right before `cast send`.
- Never print or log `PRIVATE_KEY`.
- Treat all user/subgraph values as untrusted shell input.

## Shell Input Safety (Avoid RCE)

Rules:
- Never use `eval`, `bash -c`, `sh -c` with user values.
- Only substitute addresses matching `0x` + 40 hex chars.
- Only substitute uint values containing digits only.
- Keep placeholders quoted in commands until validated.

Quick validators:
```bash
python3 - <<'PY'
import re

checks = {
  "address": ("<ADDRESS>", r"0x[a-fA-F0-9]{40}"),
  "uint": ("<UINT>", r"[0-9]+"),
}

for name, (value, pattern) in checks.items():
    if not re.fullmatch(pattern, value):
        raise SystemExit(f"invalid {name}: {value}")

print("ok")
PY
```

## Required Setup

Required env vars:
- `PRIVATE_KEY`
- `FROM_ADDRESS`
- `BASE_MAINNET_RPC`
- `DRY_RUN`
- `REALM_DIAMOND`
- `INSTALLATION_DIAMOND`
- `TILE_DIAMOND`
- `AAVEGOTCHI_DIAMOND`
- `FUD`, `FOMO`, `ALPHA`, `KEK`, `GLTR`
- `GOTCHIVERSE_SUBGRAPH_URL`
- `CORE_SUBGRAPH_URL`

Optional env vars:
- `GOLDSKY_API_KEY` for auth header (public endpoints work without it).

Use canonical defaults from `references/addresses.md`.

## Scope

Player operations only:
- Channeling
- Survey + harvest claim
- Craft/claim/reduce queues
- Equip/unequip/move/batch equip
- Installation upgrades (queued + instant)
- Access-right read/write

Out of scope:
- Owner/admin governance functions (pause/freeze/set vars/deprecations/address reconfiguration).

## Subgraph-First Workflow

1. Discover state via `GOTCHIVERSE_SUBGRAPH_URL` and `CORE_SUBGRAPH_URL`.
2. Validate current onchain values with `cast call`.
3. Simulate with `cast call --from "$FROM_ADDRESS"`.
4. Broadcast with `cast send --private-key "$PRIVATE_KEY"` only when explicitly instructed.

Canonical queries and notes: `references/subgraph.md`.

## Runbooks

### 1) Parcel Discovery + Preflight

Use:
- `references/subgraph.md` for parcel/installations/tiles/access-right discovery.
- `references/realm-recipes.md` preflight checks for:
  - parcel owner and access right
  - altar presence/level
  - gotchi lending/listing/kinship checks

### 2) Survey + Harvest

Functions:
- `startSurveying(uint256)`
- `claimAvailableAlchemica(uint256,uint256,bytes)`
- `claimAllAvailableAlchemica(uint256[],uint256,bytes)`

Use `references/realm-recipes.md` for read/simulate/broadcast commands.

### 3) Channel Alchemica

Function:
- `channelAlchemica(uint256,uint256,uint256,bytes)`

Preflight requirements:
- correct access right
- gotchi not actively listed for lending (unless lent)
- gotchi kinship is sufficient
- `getLastChanneled(gotchiId)` passed as `_lastChanneled`
- parcel altar equipped and cooldown passed

Use `references/realm-recipes.md`.

### 4) Craft Installations + Build on Parcel

Installation craft/queue functions:
- `craftInstallations(uint16[],uint40[])`
- `batchCraftInstallations((uint16,uint16,uint40)[])`
- `claimInstallations(uint256[])`
- `reduceCraftTime(uint256[],uint40[])`
- `getCraftQueue(address)`

Build functions (Realm):
- `equipInstallation(...)`
- `unequipInstallation(...)`
- `moveInstallation(...)`
- `batchEquip(...)`

Use:
- `references/installation-recipes.md`
- `references/realm-recipes.md`

### 5) Craft Tiles + Build on Parcel

Tile craft/queue functions:
- `craftTiles(uint16[])`
- `batchCraftTiles((uint16,uint16,uint40)[])`
- `claimTiles(uint256[])`
- `reduceCraftTime(uint256[],uint40[])`
- `getCraftQueue(address)`

Build functions (Realm):
- `equipTile(...)`
- `unequipTile(...)`
- `moveTile(...)`
- `batchEquip(...)`

Use:
- `references/tile-recipes.md`
- `references/realm-recipes.md`

### 6) Upgrade Installations

Functions:
- `upgradeInstallation((...),uint256,bytes,uint40)`
- `instantUpgrade((...),uint256,uint256,bytes)`
- `reduceUpgradeTime(uint256,uint256,uint40,bytes)`
- `finalizeUpgrades(uint256[])`
- `getParcelUpgradeQueue(uint256)`
- `getUserUpgradeQueueNew(address)`
- `parcelQueueEmpty(uint256)`

Use `references/installation-recipes.md`.

### 7) Access Rights

Functions:
- `setParcelsAccessRights(...)`
- `setParcelsAccessRightWithWhitelists(...)`
- `getParcelsAccessRights(...)`
- `getParcelsAccessRightsWhitelistIds(...)`

Action rights `0..6` and access modes `0..4` are documented in:
- `references/access-rights.md`

## Smoke Tests

Run these before first usage and after env changes:
- Subgraph introspection checks in `references/subgraph.md`
- Address/contract checks in `references/addresses.md`
- No-op selector checks in:
  - `references/realm-recipes.md`
  - `references/installation-recipes.md`
  - `references/tile-recipes.md`

## Failure Modes

Use `references/failure-modes.md` for:
- access-right reverts
- cooldown/kinship/channeling reverts
- coordinate/grid placement reverts
- queue state reverts
- upgrade hash/queue capacity reverts
- deprecation/GLTR/ownership mismatches



---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/addresses.md

```markdown
# Addresses / Constants (Base Mainnet)

Chain:
- Chain ID: `8453`
- Default RPC: `https://mainnet.base.org`

Diamonds:
- `REALM_DIAMOND=0x4B0040c3646D3c44B8a28Ad7055cfCF536c05372`
- `INSTALLATION_DIAMOND=0xebba5b725A2889f7f089a6cAE0246A32cad4E26b`
- `TILE_DIAMOND=0x617fdB8093b309e4699107F48812b407A7c37938`
- `AAVEGOTCHI_DIAMOND=0xA99c4B08201F2913Db8D28e71d020c4298F29dBF`

Alchemica + GLTR tokens:
- `FUD=0x2028b4043e6722Ea164946c82fe806c4a43a0fF4`
- `FOMO=0xA32137bfb57d2b6A9Fd2956Ba4B54741a6D54b58`
- `ALPHA=0x15e7CaC885e3730ce6389447BC0f7AC032f31947`
- `KEK=0xE52b9170fF4ece4C35E796Ffd74B57Dec68Ca0e5`
- `GLTR=0x4D140CE792bEdc430498c2d219AfBC33e2992c9D`

Subgraphs:
- `GOTCHIVERSE_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/gotchiverse-base/prod/gn`
- `CORE_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/aavegotchi-core-base/prod/gn`

Owner sanity (observed onchain):
- Realm/Installation/Tile owner: `0xf52398257A254D541F392667600901f710a006eD`
- FUD/FOMO/ALPHA/KEK/GLTR owner: `0x3a2E7D1E98A4a051B0766f866237c73643fDF360`

Recommended exports:
```bash
export BASE_MAINNET_RPC="${BASE_MAINNET_RPC:-https://mainnet.base.org}"

export REALM_DIAMOND="${REALM_DIAMOND:-0x4B0040c3646D3c44B8a28Ad7055cfCF536c05372}"
export INSTALLATION_DIAMOND="${INSTALLATION_DIAMOND:-0xebba5b725A2889f7f089a6cAE0246A32cad4E26b}"
export TILE_DIAMOND="${TILE_DIAMOND:-0x617fdB8093b309e4699107F48812b407A7c37938}"
export AAVEGOTCHI_DIAMOND="${AAVEGOTCHI_DIAMOND:-0xA99c4B08201F2913Db8D28e71d020c4298F29dBF}"

export FUD="${FUD:-0x2028b4043e6722Ea164946c82fe806c4a43a0fF4}"
export FOMO="${FOMO:-0xA32137bfb57d2b6A9Fd2956Ba4B54741a6D54b58}"
export ALPHA="${ALPHA:-0x15e7CaC885e3730ce6389447BC0f7AC032f31947}"
export KEK="${KEK:-0xE52b9170fF4ece4C35E796Ffd74B57Dec68Ca0e5}"
export GLTR="${GLTR:-0x4D140CE792bEdc430498c2d219AfBC33e2992c9D}"

export GOTCHIVERSE_SUBGRAPH_URL="${GOTCHIVERSE_SUBGRAPH_URL:-https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/gotchiverse-base/prod/gn}"
export CORE_SUBGRAPH_URL="${CORE_SUBGRAPH_URL:-https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/aavegotchi-core-base/prod/gn}"

export DRY_RUN="${DRY_RUN:-1}"
```

Verification snippets:
```bash
~/.foundry/bin/cast chain-id --rpc-url "$BASE_MAINNET_RPC"

~/.foundry/bin/cast code "$REALM_DIAMOND" --rpc-url "$BASE_MAINNET_RPC" | wc -c
~/.foundry/bin/cast code "$INSTALLATION_DIAMOND" --rpc-url "$BASE_MAINNET_RPC" | wc -c
~/.foundry/bin/cast code "$TILE_DIAMOND" --rpc-url "$BASE_MAINNET_RPC" | wc -c

~/.foundry/bin/cast call "$REALM_DIAMOND" 'owner()(address)' --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'owner()(address)' --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$TILE_DIAMOND" 'owner()(address)' --rpc-url "$BASE_MAINNET_RPC"

~/.foundry/bin/cast call "$FUD" 'symbol()(string)' --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$FUD" 'decimals()(uint8)' --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$FUD" 'owner()(address)' --rpc-url "$BASE_MAINNET_RPC"

~/.foundry/bin/cast call "$REALM_DIAMOND" 'getAlchemicaAddresses()(address[4])' --rpc-url "$BASE_MAINNET_RPC"
```


```

### references/subgraph.md

```markdown
# Subgraph Queries (Base)

Endpoints:
- `GOTCHIVERSE_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/gotchiverse-base/prod/gn`
- `CORE_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/aavegotchi-core-base/prod/gn`

Notes:
- Subgraph `Bytes` filters should use lowercase addresses.
- Use gotchiverse subgraph for parcel/installations/tiles state.
- Use core subgraph for supporting Aavegotchi/market context.

## Reachability Smoke Tests

```bash
curl -s "$GOTCHIVERSE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{"query":"{ __schema { queryType { fields { name } } } }"}' \
  | python3 -c 'import json,sys; f=[x["name"] for x in json.load(sys.stdin)["data"]["__schema"]["queryType"]["fields"]]; print([n for n in ("parcel","parcels","installationTypes","tileTypes","parcelAccessRights") if n in f])'

curl -s "$CORE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{"query":"{ __schema { queryType { fields { name } } } }"}' \
  | python3 -c 'import json,sys; f=[x["name"] for x in json.load(sys.stdin)["data"]["__schema"]["queryType"]["fields"]]; print([n for n in ("aavegotchi","erc721Listings","erc1155Listings") if n in f])'
```

## Parcel by ID

```bash
curl -s "$GOTCHIVERSE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
  "query":"query($id:ID!){ parcel(id:$id){ id tokenId parcelId owner coordinateX coordinateY district size surveyRound lastChanneledAlchemica lastClaimedAlchemica remainingAlchemica totalAlchemicaClaimed equippedInstallationsBalance equippedTilesBalance equippedInstallations{ id installationType name level alchemicaType capacity harvestRate craftTime prerequisites alchemicaCost } equippedTiles{ id tileType name width height craftTime alchemicaCost } } }",
  "variables":{"id":"59"}
}'
```

## Parcels by Owner

```bash
curl -s "$GOTCHIVERSE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
  "query":"query($owner:Bytes!){ parcels(first:50, orderBy: tokenId, orderDirection: asc, where:{owner:$owner}){ id tokenId parcelId owner size surveyRound remainingAlchemica equippedInstallationsBalance equippedTilesBalance } }",
  "variables":{"owner":"<FROM_ADDRESS_LOWERCASE>"}
}'
```

## Equipped Installations for a Parcel

```bash
curl -s "$GOTCHIVERSE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
  "query":"query($parcelId:String!){ installations(where:{parcel:$parcelId, equipped:true}){ id x y owner parcel{ id tokenId parcelId } type{ id name installationType level alchemicaType capacity harvestRate craftTime nextLevelId prerequisites alchemicaCost spillRate spillRadius } } }",
  "variables":{"parcelId":"59"}
}'
```

## Equipped Tiles for a Parcel

```bash
curl -s "$GOTCHIVERSE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
  "query":"query($parcelId:String!){ tiles(where:{parcel:$parcelId, equipped:true}){ id x y owner parcel{ id tokenId parcelId } type{ id name tileType width height craftTime alchemicaCost } } }",
  "variables":{"parcelId":"59"}
}'
```

## Installation and Tile Types

```bash
curl -s "$GOTCHIVERSE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
  "query":"{ installationTypes(first:1000){ id name installationType level alchemicaType craftTime harvestRate capacity nextLevelId upgradeQueueBoost prerequisites deprecated deprecatedAt alchemicaCost spillRate spillRadius amount } }"
}'

curl -s "$GOTCHIVERSE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
  "query":"{ tileTypes(first:1000){ id name tileType width height craftTime deprecated deprecatedAt alchemicaCost amount uri } }"
}'
```

## Parcel Access Rights

```bash
curl -s "$GOTCHIVERSE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
  "query":"query($parcelId:String!){ parcelAccessRights(where:{parcel:$parcelId}, orderBy:actionRight, orderDirection:asc){ id actionRight accessRight whitelistId parcel{ id tokenId owner } } }",
  "variables":{"parcelId":"59"}
}'
```

## Core Subgraph: Gotchi Context

```bash
curl -s "$CORE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
  "query":"query($id:ID!){ aavegotchi(id:$id){ id name kinship } }",
  "variables":{"id":"100"}
}'
```

## Core Subgraph: Active Parcel Listings (Optional Market Context)

```bash
curl -s "$CORE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
  "query":"query($parcelContract:Bytes!){ erc721Listings(first:50, orderBy:timeCreated, orderDirection:desc, where:{cancelled:false, timePurchased:\"0\", erc721TokenAddress:$parcelContract}){ id tokenId seller priceInWei timeCreated } }",
  "variables":{"parcelContract":"0x4b0040c3646d3c44b8a28ad7055cfcf536c05372"}
}'
```

```

### references/realm-recipes.md

```markdown
# Realm Recipes (Foundry cast)

All commands assume defaults from `references/addresses.md` and use:
- `~/.foundry/bin/cast call` for simulation/read
- `~/.foundry/bin/cast send` for broadcast

## Global Preflight

```bash
~/.foundry/bin/cast chain-id --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast wallet address --private-key "$PRIVATE_KEY"

~/.foundry/bin/cast call "$REALM_DIAMOND" 'owner()(address)' --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getAlchemicaAddresses()(address[4])' --rpc-url "$BASE_MAINNET_RPC"
```

## Parcel Reads

Parcel snapshot:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" \
  'getParcelInfo(uint256)((string,string,address,uint256,uint256,uint256,uint256,uint256[4],uint256,uint256,uint256[4],(uint256,uint256)[],(uint256,uint256)[],uint256,uint256))' \
  "<PARCEL_ID>" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Available and remaining alchemica:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getAvailableAlchemica(uint256)(uint256[4])' "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getRealmAlchemica(uint256)(uint256[4])' "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$REALM_DIAMOND" 'lastClaimedAlchemica(uint256)(uint256)' "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
```

Upgrade queue limits on parcel:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getParcelUpgradeQueueLength(uint256)(uint256)' "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getParcelUpgradeQueueCapacity(uint256)(uint256)' "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
```

## Access Right Preflight

Read access-right and whitelist id for a parcel/action:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getParcelsAccessRights(uint256[],uint256[])(uint256[])' "[<PARCEL_ID>]" "[<ACTION_RIGHT>]" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getParcelsAccessRightsWhitelistIds(uint256[],uint256[])(uint256[])' "[<PARCEL_ID>]" "[<ACTION_RIGHT>]" --rpc-url "$BASE_MAINNET_RPC"
```

Explicit verifier (reverts if unauthorized):
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'verifyAccessRight(uint256,uint256,uint256,address)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<ACTION_RIGHT>" "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Channeling Preflight

Gotchi lending/listing/kinship:
```bash
~/.foundry/bin/cast call "$AAVEGOTCHI_DIAMOND" 'isAavegotchiListed(uint32)(bool)' "<GOTCHI_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$AAVEGOTCHI_DIAMOND" 'isAavegotchiLent(uint32)(bool)' "<GOTCHI_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$AAVEGOTCHI_DIAMOND" 'kinship(uint256)(uint256)' "<GOTCHI_ID>" --rpc-url "$BASE_MAINNET_RPC"
```

Current channeling timestamps:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getLastChanneled(uint256)(uint256)' "<GOTCHI_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getParcelLastChanneled(uint256)(uint256)' "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getAltarId(uint256)(uint256)' "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
```

## Start Surveying

Simulate:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'startSurveying(uint256)' "<PARCEL_ID>" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Broadcast:
```bash
~/.foundry/bin/cast send "$REALM_DIAMOND" 'startSurveying(uint256)' "<PARCEL_ID>" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Claim Available Alchemica

Single parcel:

Simulate:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'claimAvailableAlchemica(uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" 0x \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Broadcast:
```bash
~/.foundry/bin/cast send "$REALM_DIAMOND" 'claimAvailableAlchemica(uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" 0x \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Multiple parcels:

Simulate:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'claimAllAvailableAlchemica(uint256[],uint256,bytes)' \
  "[<PARCEL_ID_1>,<PARCEL_ID_2>]" "<GOTCHI_ID>" 0x \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Broadcast:
```bash
~/.foundry/bin/cast send "$REALM_DIAMOND" 'claimAllAvailableAlchemica(uint256[],uint256,bytes)' \
  "[<PARCEL_ID_1>,<PARCEL_ID_2>]" "<GOTCHI_ID>" 0x \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Channel Alchemica

Simulate:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'channelAlchemica(uint256,uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<LAST_CHANNELED_FROM_getLastChanneled>" 0x \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Broadcast:
```bash
~/.foundry/bin/cast send "$REALM_DIAMOND" 'channelAlchemica(uint256,uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<LAST_CHANNELED_FROM_getLastChanneled>" 0x \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Build on Parcel (Installations)

Equip installation:
```bash
# simulate
~/.foundry/bin/cast call "$REALM_DIAMOND" 'equipInstallation(uint256,uint256,uint256,uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<INSTALLATION_ID>" "<X>" "<Y>" 0x \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$REALM_DIAMOND" 'equipInstallation(uint256,uint256,uint256,uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<INSTALLATION_ID>" "<X>" "<Y>" 0x \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Unequip installation:
```bash
# simulate
~/.foundry/bin/cast call "$REALM_DIAMOND" 'unequipInstallation(uint256,uint256,uint256,uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<INSTALLATION_ID>" "<X>" "<Y>" 0x \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$REALM_DIAMOND" 'unequipInstallation(uint256,uint256,uint256,uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<INSTALLATION_ID>" "<X>" "<Y>" 0x \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Move installation:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'moveInstallation(uint256,uint256,uint256,uint256,uint256,uint256)' \
  "<PARCEL_ID>" "<INSTALLATION_ID>" "<X0>" "<Y0>" "<X1>" "<Y1>" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Build on Parcel (Tiles)

Equip tile:
```bash
# simulate
~/.foundry/bin/cast call "$REALM_DIAMOND" 'equipTile(uint256,uint256,uint256,uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<TILE_ID>" "<X>" "<Y>" 0x \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$REALM_DIAMOND" 'equipTile(uint256,uint256,uint256,uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<TILE_ID>" "<X>" "<Y>" 0x \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Unequip tile:
```bash
# simulate
~/.foundry/bin/cast call "$REALM_DIAMOND" 'unequipTile(uint256,uint256,uint256,uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<TILE_ID>" "<X>" "<Y>" 0x \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$REALM_DIAMOND" 'unequipTile(uint256,uint256,uint256,uint256,uint256,bytes)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<TILE_ID>" "<X>" "<Y>" 0x \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Move tile:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'moveTile(uint256,uint256,uint256,uint256,uint256,uint256)' \
  "<PARCEL_ID>" "<TILE_ID>" "<X0>" "<Y0>" "<X1>" "<Y1>" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Batch Equip (Mixed Installations/Tiles)

Tuple layout:
- `types[]`: `0` installation, `1` tile
- `equip[]`: `true` equip, `false` unequip
- `ids[]`, `x[]`, `y[]` aligned by index
- `signatures[]`: legacy signatures, use `0x` for each action

Simulate example:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" \
  'batchEquip(uint256,uint256,(uint256[],bool[],uint256[],uint256[],uint256[]),bytes[])' \
  "<PARCEL_ID>" "<GOTCHI_ID>" \
  '([0,1],[true,false],[10,27],[0,4],[0,4])' \
  '[0x,0x]' \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Coordinate Sanity Check

Use this to validate an installation currently occupies a coordinate:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'checkCoordinates(uint256,uint256,uint256,uint256)' \
  "<PARCEL_ID>" "<X>" "<Y>" "<INSTALLATION_ID>" \
  --rpc-url "$BASE_MAINNET_RPC"
```


```

### references/installation-recipes.md

```markdown
# Installation Recipes (Foundry cast)

## Read / Verify Installation Context

Installation diamond wired addresses:
```bash
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'getAddresses()(address,address,address,address,address,bytes)' --rpc-url "$BASE_MAINNET_RPC"
```

Installation type data:
```bash
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" \
  'getInstallationType(uint256)((uint8,uint8,uint16,uint8,uint8,uint32,uint16,uint8,uint32,uint32,bool,uint256[4],uint256,uint256,uint256[],string))' \
  "<INSTALLATION_ID>" \
  --rpc-url "$BASE_MAINNET_RPC"

~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" \
  'getInstallationTypes(uint256[])(((uint8,uint8,uint16,uint8,uint8,uint32,uint16,uint8,uint32,uint32,bool,uint256[4],uint256,uint256,uint256[],string))[])' \
  "[<ID_1>,<ID_2>]" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Craft queue view:
```bash
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'getCraftQueue(address)((address,uint16,bool,uint40,uint256)[])' "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
```

Owned balances (wallet + parcel):
```bash
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'installationsBalances(address)((uint256,uint256)[])' "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'installationBalancesOfToken(address,uint256)((uint256,uint256)[])' "$REALM_DIAMOND" "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
```

## Craft Installations

Single craft path (`uint16[] ids`, `uint40[] gltr`):
```bash
# simulate
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'craftInstallations(uint16[],uint40[])' "[<INSTALLATION_ID>]" "[<GLTR_BLOCKS>]" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$INSTALLATION_DIAMOND" 'craftInstallations(uint16[],uint40[])' "[<INSTALLATION_ID>]" "[<GLTR_BLOCKS>]" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Batch craft path (`(uint16 installationID,uint16 amount,uint40 gltr)[]`):
```bash
# simulate
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'batchCraftInstallations((uint16,uint16,uint40)[])' \
  '[(10,1,0),(55,2,0)]' \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$INSTALLATION_DIAMOND" 'batchCraftInstallations((uint16,uint16,uint40)[])' \
  '[(10,1,0),(55,2,0)]' \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Claim crafted installations:
```bash
# simulate
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'claimInstallations(uint256[])' "[<QUEUE_ID_1>,<QUEUE_ID_2>]" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$INSTALLATION_DIAMOND" 'claimInstallations(uint256[])' "[<QUEUE_ID_1>,<QUEUE_ID_2>]" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Reduce craft time with GLTR burn:
```bash
# simulate
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'reduceCraftTime(uint256[],uint40[])' "[<QUEUE_ID>]" "[<BLOCKS_TO_REDUCE>]" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$INSTALLATION_DIAMOND" 'reduceCraftTime(uint256[],uint40[])' "[<QUEUE_ID>]" "[<BLOCKS_TO_REDUCE>]" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Upgrade Installations

Upgrade queue reads:
```bash
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'getParcelUpgradeQueue(uint256)((address,uint16,uint16,uint40,bool,uint256,uint256)[],uint256[])' "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'getUserUpgradeQueueNew(address)((address,uint16,uint16,uint40,bool,uint256,uint256)[],uint256[])' "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'parcelQueueEmpty(uint256)(bool)' "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'getUpgradeQueueId(uint256)((address,uint16,uint16,uint40,bool,uint256,uint256))' "<UPGRADE_INDEX>" --rpc-url "$BASE_MAINNET_RPC"
```

Queued upgrade (`UpgradeQueue` tuple):
- Tuple: `(owner, coordinateX, coordinateY, readyBlock, claimed, parcelId, installationId)`
- `readyBlock` and `claimed` are ignored on input and overwritten by contract.

```bash
# simulate
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" \
  'upgradeInstallation((address,uint16,uint16,uint40,bool,uint256,uint256),uint256,bytes,uint40)' \
  "($FROM_ADDRESS,<X>,<Y>,0,false,<PARCEL_ID>,<CURRENT_INSTALLATION_ID>)" "<GOTCHI_ID>" 0x "<GLTR_BLOCKS>" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$INSTALLATION_DIAMOND" \
  'upgradeInstallation((address,uint16,uint16,uint40,bool,uint256,uint256),uint256,bytes,uint40)' \
  "($FROM_ADDRESS,<X>,<Y>,0,false,<PARCEL_ID>,<CURRENT_INSTALLATION_ID>)" "<GOTCHI_ID>" 0x "<GLTR_BLOCKS>" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Instant upgrade (`InstantUpgradeParams` tuple):
- Tuple: `(coordinateX, coordinateY, targetInstallationIds[], parcelId, realmDiamond)`

```bash
# simulate
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" \
  'instantUpgrade((uint16,uint16,uint256[],uint256,address),uint256,uint256,bytes)' \
  "(<X>,<Y>,[<CURRENT_ID>,<NEXT_ID>,<NEXT2_ID>],<PARCEL_ID>,$REALM_DIAMOND)" "<TOTAL_GLTR_BLOCKS>" "<GOTCHI_ID>" 0x \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$INSTALLATION_DIAMOND" \
  'instantUpgrade((uint16,uint16,uint256[],uint256,address),uint256,uint256,bytes)' \
  "(<X>,<Y>,[<CURRENT_ID>,<NEXT_ID>,<NEXT2_ID>],<PARCEL_ID>,$REALM_DIAMOND)" "<TOTAL_GLTR_BLOCKS>" "<GOTCHI_ID>" 0x \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Reduce queued upgrade time:
```bash
# simulate
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'reduceUpgradeTime(uint256,uint256,uint40,bytes)' \
  "<UPGRADE_INDEX>" "<GOTCHI_ID>" "<BLOCKS_TO_REDUCE>" 0x \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$INSTALLATION_DIAMOND" 'reduceUpgradeTime(uint256,uint256,uint40,bytes)' \
  "<UPGRADE_INDEX>" "<GOTCHI_ID>" "<BLOCKS_TO_REDUCE>" 0x \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Finalize ready upgrades:
```bash
# simulate
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'finalizeUpgrades(uint256[])' "[<UPGRADE_INDEX_1>,<UPGRADE_INDEX_2>]" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$INSTALLATION_DIAMOND" 'finalizeUpgrades(uint256[])' "[<UPGRADE_INDEX_1>,<UPGRADE_INDEX_2>]" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Selector Sanity (No Funds)

```bash
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'craftInstallations(uint16[],uint40[])' '[]' '[]' --from "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'batchCraftInstallations((uint16,uint16,uint40)[])' '[]' --from "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'claimInstallations(uint256[])' '[]' --from "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$INSTALLATION_DIAMOND" 'finalizeUpgrades(uint256[])' '[]' --from "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
```


```

### references/tile-recipes.md

```markdown
# Tile Recipes (Foundry cast)

## Read / Verify Tile Context

Tile type data:
```bash
~/.foundry/bin/cast call "$TILE_DIAMOND" \
  'getTileType(uint256)((uint8,uint8,bool,uint16,uint32,uint256[4],string))' \
  "<TILE_ID>" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Tile craft queue:
```bash
~/.foundry/bin/cast call "$TILE_DIAMOND" 'getCraftQueue(address)((uint256,uint40,uint16,bool,address)[])' "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
```

Owned balances (wallet + parcel):
```bash
~/.foundry/bin/cast call "$TILE_DIAMOND" 'tilesBalances(address)((uint256,uint256)[])' "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$TILE_DIAMOND" 'tileBalancesOfToken(address,uint256)((uint256,uint256)[])' "$REALM_DIAMOND" "<PARCEL_ID>" --rpc-url "$BASE_MAINNET_RPC"
```

## Craft Tiles

Craft path (`uint16[]`):
```bash
# simulate
~/.foundry/bin/cast call "$TILE_DIAMOND" 'craftTiles(uint16[])' "[<TILE_ID>]" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$TILE_DIAMOND" 'craftTiles(uint16[])' "[<TILE_ID>]" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Batch craft (`(uint16 tileID,uint16 amount,uint40 gltr)[]`):
```bash
# simulate
~/.foundry/bin/cast call "$TILE_DIAMOND" 'batchCraftTiles((uint16,uint16,uint40)[])' \
  '[(27,1,0),(26,2,0)]' \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$TILE_DIAMOND" 'batchCraftTiles((uint16,uint16,uint40)[])' \
  '[(27,1,0),(26,2,0)]' \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Claim crafted tiles:
```bash
# simulate
~/.foundry/bin/cast call "$TILE_DIAMOND" 'claimTiles(uint256[])' "[<QUEUE_ID_1>,<QUEUE_ID_2>]" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$TILE_DIAMOND" 'claimTiles(uint256[])' "[<QUEUE_ID_1>,<QUEUE_ID_2>]" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Reduce craft time with GLTR:
```bash
# simulate
~/.foundry/bin/cast call "$TILE_DIAMOND" 'reduceCraftTime(uint256[],uint40[])' "[<QUEUE_ID>]" "[<BLOCKS_TO_REDUCE>]" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"

# broadcast
~/.foundry/bin/cast send "$TILE_DIAMOND" 'reduceCraftTime(uint256[],uint40[])' "[<QUEUE_ID>]" "[<BLOCKS_TO_REDUCE>]" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Build on Parcel with Tiles (Realm)

Tile equip/unequip/move are called through `REALM_DIAMOND`:
- `equipTile(uint256,uint256,uint256,uint256,uint256,bytes)`
- `unequipTile(uint256,uint256,uint256,uint256,uint256,bytes)`
- `moveTile(uint256,uint256,uint256,uint256,uint256,uint256)`

Use `references/realm-recipes.md` commands for those flows.

## Selector Sanity (No Funds)

```bash
~/.foundry/bin/cast call "$TILE_DIAMOND" 'craftTiles(uint16[])' '[]' --from "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$TILE_DIAMOND" 'batchCraftTiles((uint16,uint16,uint40)[])' '[]' --from "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$TILE_DIAMOND" 'claimTiles(uint256[])' '[]' --from "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$TILE_DIAMOND" 'reduceCraftTime(uint256[],uint40[])' '[]' '[]' --from "$FROM_ADDRESS" --rpc-url "$BASE_MAINNET_RPC"
```


```

### references/access-rights.md

```markdown
# Parcel Access Rights

Access-rights are stored on `REALM_DIAMOND` and checked by `LibRealm.verifyAccessRight`.

## Action Rights (`actionRight`)

- `0`: channel alchemica
- `1`: empty reservoir / claim available alchemica
- `2`: equip installations
- `3`: equip tiles
- `4`: unequip installations (legacy mapping)
- `5`: unequip tiles (legacy mapping)
- `6`: upgrade installations

## Access Modes (`accessRight`)

- `0`: only parcel owner
- `1`: owner or valid borrower of a lent gotchi
- `2`: whitelist only (`whitelistId` required)
- `3`: legacy blacklisted mode (no explicit enforcement branch in current library; treat as permissive/legacy)
- `4`: anyone

## Read Current Access Rights Onchain

```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'getParcelsAccessRights(uint256[],uint256[])(uint256[])' \
  "[<PARCEL_ID>]" "[<ACTION_RIGHT>]" \
  --rpc-url "$BASE_MAINNET_RPC"

~/.foundry/bin/cast call "$REALM_DIAMOND" 'getParcelsAccessRightsWhitelistIds(uint256[],uint256[])(uint256[])' \
  "[<PARCEL_ID>]" "[<ACTION_RIGHT>]" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Read Access Rights from Subgraph

```bash
curl -s "$GOTCHIVERSE_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
  "query":"query($parcelId:String!){ parcelAccessRights(where:{parcel:$parcelId}, orderBy:actionRight, orderDirection:asc){ actionRight accessRight whitelistId parcel{ tokenId owner } } }",
  "variables":{"parcelId":"<PARCEL_ID_AS_STRING>"}
}'
```

## Set Access Rights (No Whitelist)

Simulate:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'setParcelsAccessRights(uint256[],uint256[],uint256[])' \
  "[<PARCEL_ID>]" "[<ACTION_RIGHT>]" "[<ACCESS_RIGHT>]" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Broadcast:
```bash
~/.foundry/bin/cast send "$REALM_DIAMOND" 'setParcelsAccessRights(uint256[],uint256[],uint256[])' \
  "[<PARCEL_ID>]" "[<ACTION_RIGHT>]" "[<ACCESS_RIGHT>]" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Set Access Rights With Whitelist

Use when `accessRight = 2`.

Simulate:
```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'setParcelsAccessRightWithWhitelists(uint256[],uint256[],uint256[],uint32[])' \
  "[<PARCEL_ID>]" "[<ACTION_RIGHT>]" "[2]" "[<WHITELIST_ID>]" \
  --from "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```

Broadcast:
```bash
~/.foundry/bin/cast send "$REALM_DIAMOND" 'setParcelsAccessRightWithWhitelists(uint256[],uint256[],uint256[],uint32[])' \
  "[<PARCEL_ID>]" "[<ACTION_RIGHT>]" "[2]" "[<WHITELIST_ID>]" \
  --private-key "$PRIVATE_KEY" \
  --rpc-url "$BASE_MAINNET_RPC"
```

## Preflight Authorization Check

Use this to verify a sender/gotchi pair can execute an action:

```bash
~/.foundry/bin/cast call "$REALM_DIAMOND" 'verifyAccessRight(uint256,uint256,uint256,address)' \
  "<PARCEL_ID>" "<GOTCHI_ID>" "<ACTION_RIGHT>" "$FROM_ADDRESS" \
  --rpc-url "$BASE_MAINNET_RPC"
```


```

### references/failure-modes.md

```markdown
# Common Failure Modes and Fixes

## Chain / Env / Key

- `chain-id != 8453`
  - Fix: use Base mainnet RPC.
- `cast wallet address` does not equal `FROM_ADDRESS`
  - Fix: correct `PRIVATE_KEY` or `FROM_ADDRESS`.
- `Function does not exist`
  - Fix: verify contract address and function signature.

## Access and Ownership

- `LibRealm: Access Right - Only Owner`
  - Action not allowed under current parcel access mode.
  - Fix: use parcel owner wallet, or update access rights/whitelist.
- `RealmGettersAndSettersFacet: Only Parcel owner can call`
  - Setting access rights from a non-owner sender.
- `AppStorage: Only Parcel owner can call`
  - Owner-only route triggered (for example certain unequip/move flows).

## Channeling / Harvest

- `AlchemicaFacet: 8 hours claim cooldown`
  - Claim attempted too early after last claim.
- `AlchemicaFacet: Incorrect last duration`
  - `_lastChanneled` arg does not match `getLastChanneled(gotchiId)`.
- `AlchemicaFacet: Gotchi can't channel yet`
  - One channel per gotchi per day limit.
- `AlchemicaFacet: Parcel can't channel yet`
  - Parcel altar-level cooldown not elapsed.
- `AlchemicaFacet: Must equip Altar`
  - No altar on parcel.
- `AavegotchiDiamond: Gotchi CANNOT have active listing for lending`
  - Gotchi is listed and not currently lent.
- `Kinship too low to reduce`
  - Gotchi kinship cannot be reduced for channeling.

## Survey / Building Preconditions

- `AlchemicaFacet: Round not released`
  - Surveying round has not progressed.
- `AlchemicaFacet: Parcel already surveying`
  - Surveying already active for parcel.
- `RealmFacet: Must survey before equipping`
  - Harvester/reservoir equip attempted before survey progress.
- `RealmFacet: Lodge already equipped`
  - Only one lodge allowed.
- `RealmFacet: Maker already equipped or altar not equipped`
  - Buildqueue booster constraint.

## Grid / Coordinates

- `LibRealm: x exceeding width` or `LibRealm: y exceeding height`
  - Placement outside parcel dimensions.
- `LibRealm: Invalid spot`
  - Collision with existing installation/tile footprint.
- `LibRealm: wrong installationId` / `wrong tileId` / `wrong startPosition`
  - Unequip/move coordinates do not match currently placed object.

## Craft / Queue

- `InstallationFacet: Installation does not exist` / `TileFacet: Tile does not exist`
  - Invalid ID.
- `InstallationFacet: can only craft level 1`
  - Non-base level craft attempt.
- `InstallationFacet: Installation has been deprecated` / `TileFacet: Tile has been deprecated`
  - Deprecated type.
- `InstallationFacet: Too much GLTR` / `TileFacet: Too much GLTR`
  - Reduction exceeds craft time.
- `InstallationFacet: Not owner` / `TileFacet: not owner`
  - Queue is not owned by sender.
- `InstallationFacet: Installation not ready` / `TileFacet: tile not ready`
  - Queue `readyBlock` not reached.

## Upgrade

- `InstallationUpgradeFacet: Upgrade hash not unique`
  - Duplicate queued upgrade at same parcel+coords+installation.
- `LibInstallation: UpgradeQueue full`
  - Parcel queue capacity reached.
- `LibInstallation: Maximum upgrade reached`
  - No `nextLevelId`.
- `LibInstallation: Wrong installation type` / `Wrong alchemicaType` / `Wrong installation level`
  - Invalid upgrade path.
- `InstallationUpgradeFacet: Incorrect GLTR sent`
  - Instant upgrade `gltr` does not equal required total craft blocks.
- `InstallationUpgradeFacet: Failed GLTR transfer`
  - Missing GLTR balance/allowance.

## Troubleshooting Workflow

1. Re-fetch parcel/installations/tiles/access-rights from gotchiverse subgraph.
2. Re-run onchain reads (`getParcelInfo`, type getters, queue getters).
3. Re-simulate exact tx with `cast call --from "$FROM_ADDRESS"`.
4. Broadcast only after the simulation succeeds with the same arguments.


```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "cinnabarhorse",
  "slug": "aavegotchi-gotchiverse",
  "displayName": "Aavegotchi Gotchiverse",
  "latest": {
    "version": "1.0.0",
    "publishedAt": 1771659895718,
    "commit": "https://github.com/openclaw/skills/commit/8cf892c104a909b63883b4d09ddfb8faa9d8b7ce"
  },
  "history": []
}

```

aavegotchi-gotchiverse | SkillHub