Watch address
Claude Code skills that turn chia-explorer into finished workflows: address watches, price alerts, offer safety checks, NFT provenance, invoice watching.
npx -y skills add Spacetime-Technology/chia-skills --skill watch-addressAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Notify when a Chia address receives or sends XCH, CATs, or NFTs since the last run. Use when the user asks to be alerted on deposits, withdrawals, or activity at an address, or wants to "watch" a wallet. Accepts address, direction, min_amount, channel as arguments for programmatic invocation, or asks the user for whatever is missing.
SKILL.md
8.5 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it
Watch a Chia address
You are watching a Chia address for new activity since the last time this skill ran. You query chia-explorer (read-only, public coinset.org RPC) for recent coin records, diff against state on disk, and notify through whichever channel MCP the user has installed.
This skill follows the conventions in this repo's SKILLS.md. Read that if anything below is unclear.
Required capabilities
- chia-explorer (
mcp__chia-explorer__*) — mandatory, no substitute. If missing, tell the user to install it:claude mcp add chia-explorer -- npx chia-explorer. Then stop withSTATUS: failed,REASON: chia-explorer not installed. - A notification MCP — any of email (gmail / smtp), push (ntfy / pushover / pushcut), chat (slack / discord / telegram / signal), or webhook. Pick whatever's installed. If none, write the alert to
~/.chia-skills/alerts/watch-address-<timestamp>.mdand surface it inline. Don't stop the skill. - Bash + Read + Write — for state file management.
Resolve inputs
You need: $address, $direction, $min_amount, $channel.
$address—xch1...(mainnet) ortxch1...(testnet11). Required.$direction— one ofincoming(default),outgoing, orboth. Optional.$min_amount— minimum XCH amount per coin to alert on (default0, meaning every coin). Optional.$channel—email,push,slack,discord,telegram,webhook, orauto(default). Optional.
Resolve in this order:
- Skill arguments — trust them if set.
- Conversation context — an earlier turn may have named an address or a min threshold.
- Ask the user — only for what's still missing, in one consolidated message. Don't ping-pong.
If $address is still missing after asking, emit STATUS: aborted, REASON: missing required inputs.
Validate $address:
- Must start with
xch1ortxch1. Anything else, emitSTATUS: failed,REASON: not a Chia addressand stop. - Network is implied by the prefix. Pass it explicitly to chia-explorer calls anyway.
Load or initialise state
State file: ~/.chia-skills/state/watch-address__<sanitised_address>.json.
Sanitisation: lowercase, replace anything that isn't [a-z0-9] with _.
Shape:
{
"address": "xch1...",
"network": "mainnet",
"last_height": 6532109,
"last_seen_iso": "2026-05-19T14:33:00Z",
"skill_version": "0.1.0"
}
Steps:
- Read the state file. If missing, this is a first run.
- On first run: fetch the current chain peak height, record it as
last_height, write the state file, and emitSTATUS: success,EVENTS: 0, with a message like "watch started at height N — future runs will report activity since now". Do not scan history. - On subsequent runs: continue.
Use atomic writes for the state file: write to <file>.tmp, then mv over the original. Never leave a half-written state file.
Look up activity
Query chia-explorer for coin records at the address with start_height = last_height + 1 and end_height = <current peak>.
- For
$directionofincomingorboth: include records where the coin was created in this window (received). - For
$directionofoutgoingorboth: include records where the coin was spent in this window (sent). - Apply
$min_amount: drop any coin whose XCH value is below the threshold. CATs and NFTs don't have an XCH amount; alert on them regardless unless$min_amountis large enough that the user clearly only cares about XCH.
For each remaining coin, classify it via chia-explorer's puzzle-classification tools:
- Plain
p2→ XCH receive/send. - CAT → note the
asset_idand the CAT-unit amount. If the asset_id isn't a well-known one (USDS, SBX, etc.), call it "unknown CAT". - NFT → note the
launcher_id. The amount is always 1 mojo for NFTs. - DID → rare at a normal address but possible.
Fetch the current chain peak height once more after the scan; you'll write that as last_height to avoid missing coins added during the scan.
Compose the notification
Build a single message body covering all events in this run. Aim for human-readable, not a wall of JSON.
Example:
Chia watch — xch1yxq...8yl (3 new events, mainnet)
INCOMING
+1.250 XCH block 6,532,210 coin 0xabc...123
+500 USDS block 6,532,210 asset_id 0xdef...456 (CAT)
OUTGOING
-0.050 XCH block 6,532,217 coin 0x789...
Balance now: 12.347 XCH (~$617 at $50.00/XCH)
Heights scanned: 6,532,109 → 6,532,225
For fiat values, call chia-explorer's price tool once and apply to XCH amounts. If the price tool fails, drop the fiat line — don't block the alert.
Send the notification
Pick the channel:
- If
$channelis set, use that specific channel. - If
$channel = auto(default), use the first available in this priority: email, push, slack, discord, telegram, webhook. - If no channel MCP is available, write the message to
~/.chia-skills/alerts/watch-address-<iso8601>.mdand tell the user inline.
Subject line for email / Slack / push:
Chia: <N> new event(s) at <last 6 chars of address>
Body is the message composed above. Don't strip information — channel limits (Slack 4000 chars, Discord 2000) can be handled by trimming the per-event list to the first 20 entries and noting "+M more events not shown".
Update state
After successful notification (or after writing the inline fallback), update last_height to the post-scan peak you captured, update last_seen_iso to now, and write the state file atomically.
If the notification channel failed but the scan succeeded, still update state and emit STATUS: partial, REASON: notification channel failed. Next run won't redeliver these events — that's intentional; double-alerts are worse than a missed one. (To handle channel outages, run with $channel set to a backup.)
Scheduling
This skill is one-shot. To make it periodic:
- Cron /
scheduleskill — recommended for always-on monitoring. Example: every 5 minutes. /loopskill — fine for "watch this for the next hour" foreground polling.- Manual — re-invoke when you want a fresh check.
Don't run more often than every 30 seconds; coinset.org has rate limits, and chain peak only advances every ~52 seconds on average anyway.
Hard rules
- Read-only. Never sign, never push. If the user wants to act on what landed, tell them to use their wallet.
- No retroactive alerts on first run. Record current height and start fresh.
- State writes are atomic. Never corrupt the state file mid-write.
- Mojos to XCH for display. Always.
- Truncate addresses and hashes in the message body to the first 8 and last 6 chars unless the user explicitly wants full values.
- Network from prefix. If the address is
txch1..., passnetwork: "testnet11"explicitly. - Respect channel failures. If notification fails, emit
STATUS: partial, update state, and move on.
Recovery patterns
- chia-explorer call fails (network error / 5xx). Don't update state. Emit
STATUS: failed,REASON: chia-explorer call failed. Next scheduled run picks up from the samelast_height. - State file is corrupt. Back it up to
<file>.broken-<timestamp>and treat as first-run. Don't pretend to scan history. - Address is unknown to chia-explorer (no coins ever). Emit
STATUS: no_change,EVENTS: 0and write a state file with current peak — first watch on a fresh address.
Output
When you're done, emit this fenced block as the last thing in your response. A calling skill or agent will parse it; an interactive user will skim it.
STATUS: success | no_change | partial | failed | aborted
EVENTS: <count of events reported this run>
CHANNEL: <channel used> | inline | none
LAST_HEIGHT: <height written to state>
ADDRESS: <full address>
ARTIFACT: <absolute path to inline alert file> | none
REASON: <one line, only when STATUS is failed, partial, or aborted>