---
name: wallet-track
description: >
  Wallet activity monitoring and notification. Triggered when user says
  "追踪钱包" "监控地址" "追踪这个地址" "帮我盯着" "钱包动态" "地址活动"
  "track wallet" "monitor address" "watch this wallet" "notify me on TG".
  Supports Ethereum, Polygon, Arbitrum, Base, BSC.
  Notifications via Telegram (24/7) or agent polling (in-chat).
license: MIT
metadata:
  author: wallet-track
  version: "1.0.0"
---

# Wallet Track

## Startup (every session)

Before the first operation, resolve the API token:

1. **MCP mode**: call `register` or any tool — if 401, auto-register
2. **API mode**: run the token resolution block (see API Mode section below)

Token is saved to `~/.wallet-track/token`. Once you have a valid token, all operations
work without asking the user anything.

## First-Time Notification Setup

After the user tracks their first address, offer Telegram binding:
- "Open @CryptoTokenTrackBot, send /start, then tell me your ID"
- Call `bind_tg` with the ID (MCP) or `POST /api/track/user/bind-tg` (API)

## Chain Recognition

| User says | chain= |
|-----------|--------|
| Ethereum / eth / 以太坊 | eth |
| Polygon / matic / 马蹄 | matic |
| Arbitrum / arb | arb |
| Base / coinbase / base | base |
| BSC / bnb / 币安链 | bsc |

Address format: `0x` + 40 hex chars.

## How It Works

This skill works without any pre-installed tools. Two modes, auto-detected:

**API mode (universal)** — always available. Uses curl to call the REST API.
**MCP mode (faster)** — used when the MCP server is connected. Direct tool calls.

Check at startup: if `track_wallet` MCP tool exists → MCP mode. Otherwise → API mode.

## API Mode (primary path)

```bash
# ── Step 0: resolve token (do this once per session) ──
TOKEN=$(cat ~/.wallet-track/token 2>/dev/null || echo "$TRACK_API_TOKEN")
if [ -z "$TOKEN" ]; then
  TOKEN=$(curl -s -X POST "https://cryptotrack.site/api/track/user" \
    -H "Content-Type: application/json" -d '{}' | python3 -c "import sys,json;print(json.load(sys.stdin)['api_token'])")
  mkdir -p ~/.wallet-track && echo "$TOKEN" > ~/.wallet-track/token && chmod 600 ~/.wallet-track/token
fi
API="https://cryptotrack.site/api/track"

# ── Operations ──
# Track address
curl -s -X POST "$API/address" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"chain":"<eth/matic/arb/base/bsc>","address":"<0x...>","notify_channel":"telegram"}'

# List addresses
curl -s -H "Authorization: Bearer $TOKEN" "$API/address"

# Delete address
curl -s -X DELETE "$API/address" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"chain":"<chain>","address":"<addr>"}'

# Events (agent channel)
curl -s -H "Authorization: Bearer $TOKEN" "$API/events?after_id=0&limit=10"

# Subscription
curl -s -H "Authorization: Bearer $TOKEN" "$API/subscription"

# Bind Telegram
curl -s -X POST "$API/user/bind-tg" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"tg_id":"<id>"}'

# Update filter
curl -s -X POST "$API/address/filter" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"chain":"<chain>","address":"<addr>","min_usd_value":100,"direction":"in"}'

# Upgrade
curl -s -X POST "$API/upgrade" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"tx_hash":"<0x...>","plan":"pro_monthly"}'
```

## MCP Mode (when server is connected)

| Tool | When | Key Parameters |
|------|------|----------------|
| `register` | First-time setup | — |
| `track_wallet` | User tracks an address | chain, address, label, notify_channel |
| `my_wallets` | User asks "what am I tracking" | — |
| `stop_tracking` | User stops monitoring | chain, address |
| `check_events` | Poll new activity (agent channel) | — |
| `subscription_info` | User asks about quota | — |
| `bind_tg` | Bind Telegram for notifications | tg_id |

## Notification Channels

- **Telegram (default)**: 24/7, instant, no token cost. User must bind once.
- **Agent (notify_channel="agent")**: In-chat. Only while conversation is open.

## Interaction Rules

0. **Check mode first**: If MCP tools (`track_wallet`, etc.) are available, use them.
   Otherwise, use API mode (curl commands). Never tell the user "I can't do this" —
   fall back to curl.
1. **Chain first, then channel**: If the user gives an address without a chain, ask for the chain before
   anything else. Once chain + address are known, confirm the notification channel (default Telegram).
2. **Confirm before acting**: "Tracking 0xB... on Ethereum → Telegram. 1/1 used."
3. **Show quota**: Always display "X/Y addresses" after any change.
4. **Default Telegram**: Only use agent channel if user explicitly says "in chat" / "here".

## When User Tracks with Agent Channel

After `track_wallet` succeeds with `notify_channel="agent"`:

1. Set up a recurring check that calls `check_events` every 60 seconds.
   Use whatever background scheduling mechanism your platform provides.
2. Tell user: "I'll check every 60s and notify you of new activity."
3. When the user stops tracking ALL agent-channel addresses, cancel the recurring check.

## check_events — How It Works

The MCP server tracks a cursor internally. Each call returns only NEW events
since the last call. No parameters needed. Just call it.

## Notification Format (Agent Channel)

```
🔔 {label or short_addr} on {chain}
{direction_emoji} {amount} {symbol} [${usd_value}]
{→ or ←} {other_address}
🔗 {block_explorer_link}
```

Direction: 🟢 RECEIVED / 🔴 SENT. Explorer link from the `etherscan_url` field (maps to correct chain).

## Error Mapping

| API Error | Tell User |
|-----------|-----------|
| unauthorized (401) | "Let me set you up first — calling register..." (auto-call register) |
| timeout / 500 / network error | "Service is temporarily unavailable. Your tracking is not interrupted. Retry later." |
| address limit exceeded | "Free plan: 1 address used. Upgrade to Pro?" |
| already tracking | "You're already monitoring this address." |
| invalid address | "That doesn't look like a valid EVM address (0x + 40 hex chars)." |
| unsupported chain | "Supported: Ethereum, Polygon, Arbitrum, Base, BSC." |
| tg_id already bound | "This Telegram is already linked to another account." |

## Examples

```
"Track 0xd8dA...6045 on Ethereum, label it Vitalik"
→ track_wallet(chain="eth", address="0xd8da...", label="Vitalik")
→ "Tracking Vitalik on Ethereum → Telegram. 1/1 used."

"Monitor 0xBBB... on BSC, notify me here"
→ track_wallet(chain="bsc", address="0xBBB...", notify_channel="agent")
→ set up background check_events polling (every 60s)
→ "Tracking 0xBBB... on BSC → in-chat. Checking every 60s. 1/1 used."

"What am I tracking?"
→ my_wallets()

"Stop tracking Vitalik"
→ stop_tracking(chain="eth", address="0xd8da...")

"How's my quota?"
→ subscription_info()
```
