pet-operator
Delegate Aavegotchi petting rights to AAI's wallet on Base. Generate approve/revoke tx data, check approval, and maintain delegated wallet bookkeeping in pet-me-master config.
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-pet-operator
Repository
Skill path: skills/aaigotchi/pet-operator
Delegate Aavegotchi petting rights to AAI's wallet on Base. Generate approve/revoke tx data, check approval, and maintain delegated wallet bookkeeping in pet-me-master config.
Open repositoryBest for
Primary workflow: Analyze Data & AI.
Technical facets: Full Stack, Data / AI.
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 pet-operator into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding pet-operator to shared team environments
- Use pet-operator for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: pet-operator
description: Delegate Aavegotchi petting rights to AAI's wallet on Base. Generate approve/revoke tx data, check approval, and maintain delegated wallet bookkeeping in pet-me-master config.
metadata:
openclaw:
requires:
bins:
- cast
- jq
---
# pet-operator
Set or revoke AAI as pet operator for user wallets, and keep delegation bookkeeping aligned.
## Constants
- AAI operator wallet: `0xb96B48a6B190A9d509cE9312654F34E9770F2110`
- Aavegotchi Diamond: `0xA99c4B08201F2913Db8D28e71d020c4298F29dBF`
- Chain: Base mainnet (`8453`)
- RPC default: `https://mainnet.base.org`
Overridable env:
- `AAVEGOTCHI_DIAMOND`
- `AAI_OPERATOR`
- `BASE_RPC_URL`
- `PET_ME_CONFIG_FILE`
## Scripts
- `./scripts/check-approval.sh <wallet>`
- Checks `isPetOperatorForAll(owner, operator)`.
- `./scripts/generate-delegation-tx.sh <wallet>`
- Generates call data for `setPetOperatorForAll(AAI_OPERATOR, true)`.
- `./scripts/generate-revoke-tx.sh <wallet>`
- Generates call data for `setPetOperatorForAll(AAI_OPERATOR, false)`.
- `./scripts/add-delegated-wallet.sh <wallet> [name]`
- Verifies approval, fetches owned gotchi IDs, upserts into `pet-me-master` config.
- `./scripts/remove-delegated-wallet.sh <wallet>`
- Removes wallet bookkeeping entries from config.
## Config Bookkeeping
`add-delegated-wallet.sh` writes to:
- `.delegatedWallets` (preferred)
- `.wallets` (legacy compatibility, only if present)
This does not grant on-chain permissions by itself; on-chain approval must already exist.
## Security
- Operator permission only enables petting, not transfer.
- User keeps full ownership.
- Revocation is one on-chain tx away.
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### scripts/check-approval.sh
```bash
#!/usr/bin/env bash
# Check if a wallet has approved AAI as pet operator
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib.sh
source "$SCRIPT_DIR/lib.sh"
usage() {
echo "Usage: $0 <WALLET_ADDRESS>"
exit 1
}
[[ $# -eq 1 ]] || usage
WALLET="$(normalize_wallet "$1")"
require_read_tools
if check_pet_operator_approved "$WALLET"; then
echo "approved"
exit 0
fi
echo "not_approved"
exit 1
```
### scripts/generate-delegation-tx.sh
```bash
#!/usr/bin/env bash
# Generate pet operator delegation transaction details (approved=true)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib.sh
source "$SCRIPT_DIR/lib.sh"
usage() {
echo "Usage: $0 <WALLET_ADDRESS>"
exit 1
}
[[ $# -eq 1 ]] || usage
WALLET="$(normalize_wallet "$1")"
DATA="$(set_pet_operator_calldata true)"
cat <<OUT
π Pet Operator Delegation
==========================
Wallet: $WALLET
Operator: $AAI_OPERATOR (AAI)
Transaction Details:
====================
To: $AAVEGOTCHI_DIAMOND
Amount: 0 ETH
Network: Base (8453)
RPC: $BASE_RPC_URL
Hex Data:
$DATA
What this does: approves AAI to pet your gotchis (you keep ownership).
OUT
```
### scripts/generate-revoke-tx.sh
```bash
#!/usr/bin/env bash
# Generate transaction to revoke pet operator approval (approved=false)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib.sh
source "$SCRIPT_DIR/lib.sh"
usage() {
echo "Usage: $0 <WALLET_ADDRESS>"
exit 1
}
[[ $# -eq 1 ]] || usage
WALLET="$(normalize_wallet "$1")"
DATA="$(set_pet_operator_calldata false)"
cat <<OUT
π Revoke Pet Operator Delegation
=================================
Wallet: $WALLET
Revoking operator: $AAI_OPERATOR (AAI)
Transaction Details:
====================
To: $AAVEGOTCHI_DIAMOND
Amount: 0 ETH
Network: Base (8453)
RPC: $BASE_RPC_URL
Hex Data (approved=false):
$DATA
What this does: removes AAI's ability to pet your gotchis.
OUT
```
### scripts/add-delegated-wallet.sh
```bash
#!/usr/bin/env bash
# Add a delegated wallet record to pet-me-master config
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib.sh
source "$SCRIPT_DIR/lib.sh"
usage() {
echo "Usage: $0 <WALLET_ADDRESS> [NAME]"
exit 1
}
[[ $# -ge 1 ]] || usage
WALLET="$(normalize_wallet "$1")"
NAME="${2:-Delegated Wallet}"
require_read_tools
echo "π Add Delegated Wallet"
echo "======================="
echo "Wallet: $WALLET"
echo "Checking pet operator approval..."
if ! check_pet_operator_approved "$WALLET"; then
err "Wallet $WALLET has not approved AAI as pet operator. Run generate-delegation-tx.sh first."
fi
echo "β
Wallet approved"
echo "Fetching owned gotchi IDs..."
mapfile -t GOTCHI_IDS < <(fetch_wallet_gotchi_ids "$WALLET")
COUNT="${#GOTCHI_IDS[@]}"
if [ "$COUNT" -eq 0 ]; then
IDS_JSON='[]'
else
IDS_JSON="$(printf '%s\n' "${GOTCHI_IDS[@]}" | jq -R . | jq -s '.')"
fi
echo "Found $COUNT gotchi(s)"
if [ "$COUNT" -gt 0 ]; then
printf 'IDs: %s\n' "$(IFS=,; echo "${GOTCHI_IDS[*]}")"
fi
CONFIG_FILE="$PET_ME_CONFIG_FILE"
[ -f "$CONFIG_FILE" ] || err "Pet-me-master config not found: $CONFIG_FILE"
TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
ADDR_LC="$(to_lower "$WALLET")"
cp -f "$CONFIG_FILE" "${CONFIG_FILE}.bak.$(date +%Y%m%d-%H%M%S)"
jq \
--arg name "$NAME" \
--arg addr "$WALLET" \
--arg addr_lc "$ADDR_LC" \
--arg ts "$TS" \
--argjson ids "$IDS_JSON" \
'
.delegatedWallets = ((.delegatedWallets // [])
| map(select(((.address // "") | ascii_downcase) != $addr_lc))
+ [{name:$name,address:$addr,gotchiIds:$ids,approved:true,updatedAt:$ts}])
| if has("wallets") then
.wallets = ((.wallets // [])
| map(select(((.address // "") | ascii_downcase) != $addr_lc))
+ [{name:$name,address:$addr,gotchiIds:$ids}])
else
.
end
' "$CONFIG_FILE" > "${CONFIG_FILE}.tmp"
mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
echo "β
Delegated wallet saved"
echo "Config: $CONFIG_FILE"
echo "delegatedWallets count: $(jq '.delegatedWallets | length' "$CONFIG_FILE")"
```
### scripts/remove-delegated-wallet.sh
```bash
#!/usr/bin/env bash
# Remove a delegated wallet record from pet-me-master config
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib.sh
source "$SCRIPT_DIR/lib.sh"
usage() {
echo "Usage: $0 <WALLET_ADDRESS>"
exit 1
}
[[ $# -eq 1 ]] || usage
WALLET="$(normalize_wallet "$1")"
ADDR_LC="$(to_lower "$WALLET")"
CONFIG_FILE="$PET_ME_CONFIG_FILE"
[ -f "$CONFIG_FILE" ] || err "Pet-me-master config not found: $CONFIG_FILE"
BEFORE_DELEGATED="$(jq --arg addr_lc "$ADDR_LC" '[.delegatedWallets[]? | select(((.address // "") | ascii_downcase) == $addr_lc)] | length' "$CONFIG_FILE")"
BEFORE_WALLETS="$(jq --arg addr_lc "$ADDR_LC" '[.wallets[]? | select(((.address // "") | ascii_downcase) == $addr_lc)] | length' "$CONFIG_FILE")"
if [ "$BEFORE_DELEGATED" -eq 0 ] && [ "$BEFORE_WALLETS" -eq 0 ]; then
echo "β οΈ Wallet not found in delegatedWallets/wallets: $WALLET"
exit 1
fi
cp -f "$CONFIG_FILE" "${CONFIG_FILE}.bak.$(date +%Y%m%d-%H%M%S)"
jq --arg addr_lc "$ADDR_LC" '
if has("delegatedWallets") then
.delegatedWallets = ((.delegatedWallets // []) | map(select(((.address // "") | ascii_downcase) != $addr_lc)))
else . end
| if has("wallets") then
.wallets = ((.wallets // []) | map(select(((.address // "") | ascii_downcase) != $addr_lc)))
else . end
' "$CONFIG_FILE" > "${CONFIG_FILE}.tmp"
mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
echo "β
Wallet removed: $WALLET"
if jq -e '.delegatedWallets' "$CONFIG_FILE" >/dev/null 2>&1; then
echo "delegatedWallets count: $(jq '.delegatedWallets | length' "$CONFIG_FILE")"
fi
if jq -e '.wallets' "$CONFIG_FILE" >/dev/null 2>&1; then
echo "wallets count: $(jq '.wallets | length' "$CONFIG_FILE")"
fi
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### README.md
```markdown
# Pet Operator
Delegate Aavegotchi petting rights to AAI while keeping full ownership.
## What It Does
This repo helps users approve AAI's operator wallet as pet operator on Base:
- AAI operator wallet: `0xb96B48a6B190A9d509cE9312654F34E9770F2110`
- Aavegotchi Diamond: `0xA99c4B08201F2913Db8D28e71d020c4298F29dBF`
Approval call:
- `setPetOperatorForAll(address operator, bool approved)`
## Scripts
- `scripts/check-approval.sh <wallet>`
- Returns `approved` / `not_approved`
- `scripts/generate-delegation-tx.sh <wallet>`
- Prints transaction details for `approved=true`
- `scripts/generate-revoke-tx.sh <wallet>`
- Prints transaction details for `approved=false`
- `scripts/add-delegated-wallet.sh <wallet> [name]`
- Verifies approval, fetches wallet gotchi IDs, upserts into pet-me-master config (`delegatedWallets`; legacy `wallets` if present)
- `scripts/remove-delegated-wallet.sh <wallet>`
- Removes wallet from pet-me-master config tracking arrays
## Notes
- This skill does not move NFTs or tokens.
- Users can revoke anytime by sending the revoke transaction.
- Pet-me-master now supports dynamic wallet/delegation discovery; config writes are mainly operational bookkeeping.
```
### _meta.json
```json
{
"owner": "aaigotchi",
"slug": "pet-operator",
"displayName": "Pet Operator",
"latest": {
"version": "1.2.0",
"publishedAt": 1772826827393,
"commit": "https://github.com/openclaw/skills/commit/9d65f4f094a060836d346f188f03377b380604f2"
},
"history": [
{
"version": "1.1.0",
"publishedAt": 1772428338589,
"commit": "https://github.com/openclaw/skills/commit/d6c81fcf81c4e4f2b3cf8aeafb9e3dd557c625ed"
}
]
}
```
### scripts/lib.sh
```bash
#!/usr/bin/env bash
set -euo pipefail
AAVEGOTCHI_DIAMOND="${AAVEGOTCHI_DIAMOND:-0xA99c4B08201F2913Db8D28e71d020c4298F29dBF}"
AAI_OPERATOR="${AAI_OPERATOR:-0xb96B48a6B190A9d509cE9312654F34E9770F2110}"
BASE_RPC_URL="${BASE_RPC_URL:-https://mainnet.base.org}"
PET_ME_CONFIG_FILE="${PET_ME_CONFIG_FILE:-$HOME/.openclaw/workspace/skills/pet-me-master/config.json}"
err() {
echo "ERROR: $*" >&2
exit 1
}
warn() {
echo "WARN: $*" >&2
}
require_bin() {
local bin="$1"
command -v "$bin" >/dev/null 2>&1 || err "Missing required binary: $bin"
}
require_read_tools() {
require_bin cast
require_bin jq
}
is_eth_address() {
[[ "$1" =~ ^0x[0-9a-fA-F]{40}$ ]]
}
normalize_wallet() {
local wallet="$1"
is_eth_address "$wallet" || err "Invalid wallet address: $wallet"
printf '%s\n' "$wallet"
}
to_lower() {
printf '%s\n' "$1" | tr '[:upper:]' '[:lower:]'
}
set_pet_operator_calldata() {
local approved="$1"
case "$approved" in
true|false)
;;
*)
err "approved must be true|false"
;;
esac
if command -v cast >/dev/null 2>&1; then
local data
data="$(cast calldata "setPetOperatorForAll(address,bool)" "$AAI_OPERATOR" "$approved" 2>/dev/null || true)"
if [[ -n "$data" && "$data" == 0x* ]]; then
printf '%s\n' "$data"
return 0
fi
fi
if [[ "$approved" == "true" ]]; then
printf '%s\n' "0xcd675d57000000000000000000000000b96b48a6b190a9d509ce9312654f34e9770f21100000000000000000000000000000000000000000000000000000000000000001"
else
printf '%s\n' "0xcd675d57000000000000000000000000b96b48a6b190a9d509ce9312654f34e9770f21100000000000000000000000000000000000000000000000000000000000000000"
fi
}
check_pet_operator_approved() {
local wallet="$1"
local out
local norm
wallet="$(normalize_wallet "$wallet")"
out="$(cast call "$AAVEGOTCHI_DIAMOND" "isPetOperatorForAll(address,address)(bool)" "$wallet" "$AAI_OPERATOR" --rpc-url "$BASE_RPC_URL" 2>/dev/null || true)"
if [ -z "$out" ]; then
out="$(cast call "$AAVEGOTCHI_DIAMOND" "isPetOperatorForAll(address,address)" "$wallet" "$AAI_OPERATOR" --rpc-url "$BASE_RPC_URL" 2>/dev/null || true)"
fi
norm="$(printf '%s' "$out" | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')"
case "$norm" in
true|0x1|0x01|0x0000000000000000000000000000000000000000000000000000000000000001)
return 0
;;
false|0x0|0x00|0x0000000000000000000000000000000000000000000000000000000000000000)
return 1
;;
*)
warn "Unexpected isPetOperatorForAll response: ${out:-<empty>}"
return 1
;;
esac
}
fetch_wallet_gotchi_ids() {
local wallet="$1"
local out
wallet="$(normalize_wallet "$wallet")"
out="$(cast call "$AAVEGOTCHI_DIAMOND" "tokenIdsOfOwner(address)(uint32[])" "$wallet" --rpc-url "$BASE_RPC_URL" --json 2>/dev/null || true)"
if [ -n "$out" ]; then
printf '%s' "$out" | jq -r '.[0][]? | tostring' 2>/dev/null | sed '/^$/d' || true
return 0
fi
local balance_hex
local count
balance_hex="$(cast call "$AAVEGOTCHI_DIAMOND" "balanceOf(address)(uint256)" "$wallet" --rpc-url "$BASE_RPC_URL" 2>/dev/null || true)"
[ -n "$balance_hex" ] || return 0
count=$((16#${balance_hex#0x}))
local i token_hex
for ((i=0; i<count; i++)); do
token_hex="$(cast call "$AAVEGOTCHI_DIAMOND" "tokenOfOwnerByIndex(address,uint256)(uint256)" "$wallet" "$i" --rpc-url "$BASE_RPC_URL" 2>/dev/null || true)"
[ -n "$token_hex" ] || continue
printf '%s\n' "$((16#${token_hex#0x}))"
done
}
```