gotchi-equip
Equip, unequip, and inspect Aavegotchi wearables on Base via Bankr submissions.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-gotchi-equip
Repository
Skill path: skills/aaigotchi/gotchi-equip
Equip, unequip, and inspect Aavegotchi wearables on Base via Bankr submissions.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack.
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 gotchi-equip into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding gotchi-equip to shared team environments
- Use gotchi-equip for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: gotchi-equip
description: Equip, unequip, and inspect Aavegotchi wearables on Base via Bankr submissions.
homepage: https://github.com/aaigotchi/gotchi-equip-skill
metadata:
openclaw:
requires:
bins:
- node
- jq
- curl
env:
- BANKR_API_KEY
skills:
- bankr
---
# gotchi-equip
Manage wearable loadouts for your gotchis.
## Scripts
- `./scripts/equip.sh <gotchi-id> <slot=wearableId> [slot=wearableId...]`
- Updates selected slots while preserving existing equipped slots.
- `./scripts/unequip-all.sh <gotchi-id>`
- Sets all 16 wearable slots to `0`.
- `./scripts/show-equipped.sh <gotchi-id>`
- Shows currently equipped wearables from the Base subgraph.
## Slot names
`body`, `face`, `eyes`, `head`, `left-hand`, `right-hand`, `pet`, `background`
## Safety notes
- Gotchi ID is validated as numeric input.
- API key is resolved from env/systemd/bankr config paths.
- Equip flow fetches current loadout first to avoid accidental unequip of unspecified slots.
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### scripts/equip.sh
```bash
#!/usr/bin/env bash
set -euo pipefail
# gotchi-equip: Equip wearables on an Aavegotchi
# Usage: equip.sh <gotchi-id> <slot1=wearableId1> [slot2=wearableId2] ...
# Example: equip.sh 9638 right-hand=64 left-hand=65 head=90
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
# shellcheck source=common.sh
source "$SCRIPT_DIR/common.sh"
usage() {
cat <<USAGE
Usage: ./scripts/equip.sh <gotchi-id> <slot=wearableId> [slot2=wearableId2] ...
Valid slots: body, face, eyes, head, left-hand, right-hand, pet, background
Examples:
./scripts/equip.sh 9638 right-hand=64
./scripts/equip.sh 9638 head=90 pet=151 right-hand=64
USAGE
}
if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
usage
exit 0
fi
if [ "$#" -lt 2 ]; then
usage
exit 1
fi
require_bin node
require_bin jq
require_bin curl
GOTCHI_ID="$1"
shift
validate_gotchi_id "$GOTCHI_ID"
# Build wearables JSON object safely
WEARABLES_JSON='{}'
for arg in "$@"; do
if [[ ! "$arg" =~ ^([a-z-]+)=([0-9]+)$ ]]; then
echo "Invalid format: $arg"
echo "Expected: slot=wearableId (e.g., right-hand=64)"
exit 1
fi
SLOT="${BASH_REMATCH[1]}"
WEARABLE_ID="${BASH_REMATCH[2]}"
WEARABLES_JSON="$(echo "$WEARABLES_JSON" | jq -c --arg slot "$SLOT" --argjson id "$WEARABLE_ID" '. + {($slot): $id}')"
done
# Preserve existing loadout: fetch current 16-slot wearables first.
CURRENT_WEARABLES_JSON="$(fetch_current_wearables "$GOTCHI_ID")"
echo "Gotchi: #$GOTCHI_ID"
echo "Requested updates: $WEARABLES_JSON"
echo
TEMP_SCRIPT="$(mktemp /tmp/gotchi-equip-script-XXXXXX.js)"
TEMP_TX="$(mktemp /tmp/gotchi-equip-tx-XXXXXX.json)"
cleanup() {
rm -f "$TEMP_SCRIPT" "$TEMP_TX"
}
trap cleanup EXIT
cat > "$TEMP_SCRIPT" <<'NODE_EOF'
const { buildEquipTransaction } = require(process.argv[2]);
const fs = require('fs');
const gotchiId = process.argv[3];
const wearables = JSON.parse(process.argv[4]);
const currentWearables = JSON.parse(process.argv[5]);
const outFile = process.argv[6];
try {
const txData = buildEquipTransaction(gotchiId, wearables, currentWearables);
console.log('Transaction prepared:');
console.log(' To:', txData.transaction.to);
console.log(' Chain:', txData.transaction.chainId);
console.log(' Description:', txData.description);
console.log('');
fs.writeFileSync(outFile, JSON.stringify(txData, null, 2));
console.log('Saved transaction payload to temp file');
} catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
NODE_EOF
cd "$SKILL_DIR"
node "$TEMP_SCRIPT" "$SKILL_DIR/lib/equip-lib.js" "$GOTCHI_ID" "$WEARABLES_JSON" "$CURRENT_WEARABLES_JSON" "$TEMP_TX"
echo "Submitting transaction via Bankr..."
API_KEY="$(resolve_bankr_api_key)"
RESPONSE="$(curl -sS -X POST "https://api.bankr.bot/agent/submit" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TEMP_TX")"
if ! echo "$RESPONSE" | jq -e . >/dev/null 2>&1; then
echo "Non-JSON response from Bankr:"
echo "$RESPONSE"
exit 1
fi
echo "$RESPONSE" | jq '.'
SUCCESS="$(echo "$RESPONSE" | jq -r '.success // false')"
if [ "$SUCCESS" = "true" ]; then
TX_HASH="$(echo "$RESPONSE" | jq -r '.transactionHash // empty')"
echo
echo "SUCCESS: wearables equipped"
if [ -n "$TX_HASH" ]; then
echo "Transaction: $TX_HASH"
echo "BaseScan: https://basescan.org/tx/$TX_HASH"
fi
else
ERR_MSG="$(echo "$RESPONSE" | jq -r '.error // .message // "Transaction failed"')"
echo
echo "Transaction failed: $ERR_MSG"
exit 1
fi
```
### scripts/unequip-all.sh
```bash
#!/usr/bin/env bash
set -euo pipefail
# gotchi-equip: Unequip all wearables from an Aavegotchi
# Usage: unequip-all.sh <gotchi-id>
# Example: unequip-all.sh 9638
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
# shellcheck source=common.sh
source "$SCRIPT_DIR/common.sh"
usage() {
cat <<USAGE
Usage: ./scripts/unequip-all.sh <gotchi-id>
Example:
./scripts/unequip-all.sh 9638
USAGE
}
if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
usage
exit 0
fi
if [ "$#" -ne 1 ]; then
usage
exit 1
fi
require_bin node
require_bin jq
require_bin curl
GOTCHI_ID="$1"
validate_gotchi_id "$GOTCHI_ID"
echo "Gotchi: #$GOTCHI_ID"
echo "Action: Unequip all wearables"
echo
TEMP_SCRIPT="$(mktemp /tmp/gotchi-unequip-script-XXXXXX.js)"
TEMP_TX="$(mktemp /tmp/gotchi-unequip-tx-XXXXXX.json)"
cleanup() {
rm -f "$TEMP_SCRIPT" "$TEMP_TX"
}
trap cleanup EXIT
cat > "$TEMP_SCRIPT" <<'NODE_EOF'
const { buildUnequipAllTransaction } = require(process.argv[2]);
const fs = require('fs');
const gotchiId = process.argv[3];
const outFile = process.argv[4];
try {
const txData = buildUnequipAllTransaction(gotchiId);
console.log('Transaction prepared:');
console.log(' To:', txData.transaction.to);
console.log(' Chain:', txData.transaction.chainId);
console.log(' Description:', txData.description);
console.log('');
fs.writeFileSync(outFile, JSON.stringify(txData, null, 2));
console.log('Saved transaction payload to temp file');
} catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
NODE_EOF
cd "$SKILL_DIR"
node "$TEMP_SCRIPT" "$SKILL_DIR/lib/equip-lib.js" "$GOTCHI_ID" "$TEMP_TX"
echo "Submitting transaction via Bankr..."
API_KEY="$(resolve_bankr_api_key)"
RESPONSE="$(curl -sS -X POST "https://api.bankr.bot/agent/submit" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d @"$TEMP_TX")"
if ! echo "$RESPONSE" | jq -e . >/dev/null 2>&1; then
echo "Non-JSON response from Bankr:"
echo "$RESPONSE"
exit 1
fi
echo "$RESPONSE" | jq '.'
SUCCESS="$(echo "$RESPONSE" | jq -r '.success // false')"
if [ "$SUCCESS" = "true" ]; then
TX_HASH="$(echo "$RESPONSE" | jq -r '.transactionHash // empty')"
echo
echo "SUCCESS: all wearables unequipped"
if [ -n "$TX_HASH" ]; then
echo "Transaction: $TX_HASH"
echo "BaseScan: https://basescan.org/tx/$TX_HASH"
fi
else
ERR_MSG="$(echo "$RESPONSE" | jq -r '.error // .message // "Transaction failed"')"
echo
echo "Transaction failed: $ERR_MSG"
exit 1
fi
```
### scripts/show-equipped.sh
```bash
#!/usr/bin/env bash
set -euo pipefail
# gotchi-equip: Show currently equipped wearables on an Aavegotchi
# Usage: show-equipped.sh <gotchi-id>
# Example: show-equipped.sh 9638
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=common.sh
source "$SCRIPT_DIR/common.sh"
usage() {
cat <<USAGE
Usage: ./scripts/show-equipped.sh <gotchi-id>
Example:
./scripts/show-equipped.sh 9638
USAGE
}
if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
usage
exit 0
fi
if [ "$#" -ne 1 ]; then
usage
exit 1
fi
require_bin jq
require_bin curl
GOTCHI_ID="$1"
validate_gotchi_id "$GOTCHI_ID"
echo "Fetching equipped wearables for gotchi #$GOTCHI_ID"
echo
GOTCHI_JSON="$(fetch_gotchi_subgraph_json "$GOTCHI_ID")"
NAME="$(echo "$GOTCHI_JSON" | jq -r '.name // "Unknown"')"
EQUIPPED="$(echo "$GOTCHI_JSON" | jq -c '(.equippedWearables // [])')"
echo "==================================================================="
echo "Gotchi: #$GOTCHI_ID \"$NAME\""
echo
echo "Equipped wearables:"
echo
SLOTS=("Body" "Face" "Eyes" "Head" "Left Hand" "Right Hand" "Pet" "Background")
HAS_ANY=0
for i in {0..7}; do
WEARABLE_ID="$(echo "$EQUIPPED" | jq -r ".[$i] // 0")"
if [ "$WEARABLE_ID" != "0" ] && [ "$WEARABLE_ID" != "null" ]; then
HAS_ANY=1
echo " ${SLOTS[$i]}: Wearable ID $WEARABLE_ID"
fi
done
if [ "$HAS_ANY" -eq 0 ]; then
echo " (none equipped)"
fi
echo
echo "==================================================================="
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### README.md
```markdown
# gotchi-equip
Equip and manage wearables on your Aavegotchi NFTs on Base mainnet.
## Features
- Equip one or multiple slots in one transaction
- Preserves existing loadout when you update only selected slots
- Unequip all wearables
- View currently equipped items
- Secure Bankr transaction submission
## Quick Start
```bash
npm install
# Equip one slot (keeps all other slots unchanged)
./scripts/equip.sh 9638 right-hand=64
# Equip multiple slots
./scripts/equip.sh 9638 head=90 pet=151 right-hand=64
# Show equipped
./scripts/show-equipped.sh 9638
# Unequip all
./scripts/unequip-all.sh 9638
```
## Valid Slots
- `body`
- `face`
- `eyes`
- `head`
- `left-hand`
- `right-hand`
- `pet`
- `background`
## Requirements
- `node`
- `jq`
- `curl`
- Bankr API key
Bankr API key resolution order:
1. `BANKR_API_KEY`
2. user systemd environment (`systemctl --user show-environment`)
3. `~/.openclaw/skills/bankr/config.json`
4. `~/.openclaw/workspace/skills/bankr/config.json`
```
### _meta.json
```json
{
"owner": "aaigotchi",
"slug": "gotchi-equip",
"displayName": "Gotchi Equip",
"latest": {
"version": "1.0.3",
"publishedAt": 1772826848767,
"commit": "https://github.com/openclaw/skills/commit/29b40e78ffdcdfa64e978d3f661310eb395827b7"
},
"history": [
{
"version": "1.0.2",
"publishedAt": 1771522462959,
"commit": "https://github.com/openclaw/skills/commit/960c8f0f4ecf873fa18e1561f34f12eaaf964d71"
},
{
"version": "1.0.0",
"publishedAt": 1771384935820,
"commit": "https://github.com/openclaw/skills/commit/c693e2e896406934bc140226465d83782e022526"
}
]
}
```
### scripts/common.sh
```bash
#!/usr/bin/env bash
SUBGRAPH_URL="https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/aavegotchi-core-base/prod/gn"
die() {
echo "ERROR: $*" >&2
exit 1
}
require_bin() {
local bin="$1"
command -v "$bin" >/dev/null 2>&1 || die "Missing required binary: $bin"
}
validate_gotchi_id() {
local gotchi_id="$1"
[[ "$gotchi_id" =~ ^[0-9]+$ ]] || die "Invalid gotchi ID: $gotchi_id"
}
resolve_bankr_api_key() {
local key="${BANKR_API_KEY:-}"
if [ -z "$key" ] && command -v systemctl >/dev/null 2>&1; then
key="$(systemctl --user show-environment 2>/dev/null | sed -n 's/^BANKR_API_KEY=//p' | head -n1 || true)"
fi
if [ -z "$key" ] && [ -f "$HOME/.openclaw/skills/bankr/config.json" ]; then
key="$(jq -r '.apiKey // empty' "$HOME/.openclaw/skills/bankr/config.json" 2>/dev/null || true)"
fi
if [ -z "$key" ] && [ -f "$HOME/.openclaw/workspace/skills/bankr/config.json" ]; then
key="$(jq -r '.apiKey // empty' "$HOME/.openclaw/workspace/skills/bankr/config.json" 2>/dev/null || true)"
fi
[ -n "$key" ] || die "BANKR_API_KEY missing (env/systemd/bankr config)"
printf '%s\n' "$key"
}
fetch_gotchi_subgraph_json() {
local gotchi_id="$1"
local payload response
require_bin curl
require_bin jq
validate_gotchi_id "$gotchi_id"
payload="$(jq -n --arg id "$gotchi_id" '{
query: "query($id: String!) { aavegotchi(id: $id) { id name equippedWearables } }",
variables: { id: $id }
}')"
response="$(curl -sS "$SUBGRAPH_URL" -H 'content-type: application/json' --data "$payload")"
if ! echo "$response" | jq -e . >/dev/null 2>&1; then
die "Subgraph returned non-JSON response"
fi
if echo "$response" | jq -e '.errors and (.errors | length > 0)' >/dev/null 2>&1; then
echo "$response" | jq '.errors' >&2
die "Subgraph query returned errors"
fi
local gotchi_json
gotchi_json="$(echo "$response" | jq -c '.data.aavegotchi // null')"
[ "$gotchi_json" != "null" ] || die "Gotchi #$gotchi_id not found"
printf '%s\n' "$gotchi_json"
}
fetch_current_wearables() {
local gotchi_id="$1"
local gotchi_json wearables
gotchi_json="$(fetch_gotchi_subgraph_json "$gotchi_id")"
wearables="$(echo "$gotchi_json" | jq -c '(.equippedWearables // []) as $w | ($w + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])[0:16]')"
if ! echo "$wearables" | jq -e 'type == "array" and length == 16 and all(.[]; (type == "number") and (. >= 0) and (. <= 65535))' >/dev/null 2>&1; then
die "Invalid equippedWearables shape from subgraph"
fi
printf '%s\n' "$wearables"
}
```