文件预览

SKILL.md

查看 Chia WalletConnect - Telegram Verification 技能包中的文件内容。

文件内容

SKILL.md

---
name: chia-walletconnect
description: Telegram Web App for Chia wallet verification via WalletConnect and Sage. Enables cryptographic proof of wallet ownership through signature verification using MintGarden API.
metadata: {"clawdbot":{"requires":{"bins":["node"]},"install":[]}}
---

# Chia WalletConnect Skill

Verify Chia wallet ownership via Telegram using WalletConnect integration with Sage Wallet.

## What It Does

This skill provides a **Telegram Mini App** (Web App) that enables users to:
1. Connect their Sage Wallet via WalletConnect v2
2. Sign a challenge message cryptographically
3. Verify wallet ownership via MintGarden's signature verification API
4. Return verification status to your Telegram bot

**Use Cases:**
- NFT-gated Telegram groups
- Airdrop eligibility verification
- Web3-style authentication
- DAO voting authentication
- Proof of token holdings

## Architecture

```
/verify command → Web App button → WalletConnect → Sage signs → Verification
```

The user never leaves Telegram. The entire flow happens in-app via the Telegram Web App API.

## Installation

```bash
# Install via ClawdHub
clawdhub install chia-walletconnect

# Install dependencies
cd skills/chia-walletconnect
npm install

# Make CLI executable
chmod +x cli.js
```

## Deployment

### Step 1: Deploy Web App

Deploy the `webapp/` folder to a public HTTPS URL:

**Vercel (Recommended):**
```bash
cd skills/chia-walletconnect/webapp
vercel
# Copy the URL (e.g., https://chia-verify.vercel.app)
```

**Netlify:**
```bash
cd skills/chia-walletconnect/webapp
netlify deploy --prod
```

**Your Server:**
```bash
# Start Express server
npm start
# Expose via ngrok or reverse proxy
```

### Step 2: Register with BotFather

1. Message [@BotFather](https://t.me/BotFather)
2. Send `/newapp` or `/editapp`
3. Select your bot
4. **Web App URL:** Enter deployed URL
5. **Short Name:** `verify`

### Step 3: Add to Bot

#### Using Clawdbot Message Tool

```javascript
// Send /verify command handler
message({
  action: 'send',
  target: chatId,
  message: 'Click below to verify your Chia wallet:',
  buttons: [[{
    text: '🌱 Verify Wallet',
    web_app: { url: 'https://your-app.vercel.app' }
  }]]
});
```

#### Handling Verification Response

```javascript
// In your bot's web_app_data handler
bot.on('web_app_data', async (msg) => {
  const data = JSON.parse(msg.web_app_data.data);
  const { address, message, signature, publicKey, userId } = data;
  
  // Verify signature
  const { verifySignature } = require('./skills/chia-walletconnect/lib/verify');
  const result = await verifySignature(address, message, signature, publicKey);
  
  if (result.verified) {
    // Wallet verified! Grant access, record verification, etc.
    message({
      action: 'send',
      target: msg.chat.id,
      message: `✅ Wallet verified!\n\nAddress: ${address}`
    });
    
    // Store verification
    // await db.saveVerification(userId, address);
  } else {
    message({
      action: 'send',
      target: msg.chat.id,
      message: `❌ Verification failed: ${result.error}`
    });
  }
});
```

## CLI Usage

The skill includes a CLI for testing:

```bash
# Generate challenge message
node cli.js challenge xch1abc... telegram_user_123

# Verify signature manually
node cli.js verify xch1abc... "message" "signature" "pubkey"

# Validate address format
node cli.js validate xch1abc...

# Start development server
node cli.js server
```

## API Reference

### MintGarden Signature Verification

**Endpoint:** `POST https://api.mintgarden.io/address/verify_signature`

```json
{
  "address": "xch1abc...",
  "message": "Verify ownership of Chia wallet:...",
  "signature": "hex_signature",
  "pubkey": "hex_public_key"
}
```

**Response:**
```json
{
  "verified": true
}
```

### CHIP-0002 Methods (WalletConnect)

| Method | Purpose |
|--------|---------|
| `chip0002_getPublicKeys` | Fetch public keys from wallet |
| `chip0002_signMessage` | Request message signature |
| `chia_getCurrentAddress` | Get current receive address |

## Verification Flow

```
1. User sends /verify to bot
2. Bot responds with Web App button
3. User taps button → Mini App opens in Telegram
4. Mini App initializes WalletConnect
5. User connects Sage Wallet
6. Challenge message generated (includes nonce + timestamp)
7. User signs message in Sage Wallet
8. Signature sent back to bot via Telegram.WebApp.sendData()
9. Bot verifies signature with MintGarden API
10. Bot confirms verification success/failure
```

**Time:** ~5-10 seconds for full flow (user-dependent)

## Configuration

### Environment Variables

Create `.env` in skill folder:

```env
PORT=3000
WALLETCONNECT_PROJECT_ID=your-project-id
MINTGARDEN_API_URL=https://api.mintgarden.io
```

### Get WalletConnect Project ID

1. Visit [WalletConnect Cloud](https://cloud.walletconnect.com)
2. Create a new project
3. Copy your Project ID
4. Update in `webapp/app.js`

**Default Project ID:**  
The skill includes `6d377259062295c0f6312b4f3e7a5d9b` (Dracattus reference). For production, use your own.

## Security

### What's Protected

- ✅ Challenge nonces prevent replay attacks
- ✅ Timestamps expire after 5 minutes
- ✅ MintGarden cryptographic verification
- ✅ No private keys ever requested
- ✅ HTTPS enforced by Telegram

### Best Practices

1. **Store verifications securely** — Use encrypted database
2. **Rate limit** — Prevent spam verification attempts
3. **Link to Telegram user ID** — Prevent address spoofing
4. **Implement cooldown** — 1 verification per user per day
5. **Log attempts** — Audit trail for security

### Production Checklist

- [ ] Deploy to HTTPS URL (required by Telegram)
- [ ] Use your own WalletConnect Project ID
- [ ] Enable CORS only for your domain
- [ ] Add rate limiting on webhook endpoints
- [ ] Store verifications in persistent database
- [ ] Implement retry logic for network errors
- [ ] Set up monitoring/alerts

## Files

```
chia-walletconnect/
├── webapp/
│   ├── index.html        # Telegram Web App UI
│   ├── app.js            # WalletConnect logic
│   └── styles.css        # Styling
├── lib/
│   ├── challenge.js      # Challenge generation
│   └── verify.js         # MintGarden API client
├── server/
│   └── index.js          # Express webhook server
├── cli.js                # CLI interface
├── package.json          # Dependencies
├── SKILL.md              # This file
└── README.md             # Full documentation
```

## Troubleshooting

### Web App Doesn't Load

- Verify HTTPS deployment (Telegram requires SSL)
- Check URL is publicly accessible
- Test URL directly in browser
- Review browser console for errors

### WalletConnect Connection Fails

- Ensure Sage Wallet is latest version
- Try manual URI paste instead of QR
- Check WalletConnect Project ID is valid
- Verify Sage supports WalletConnect v2

### Signature Verification Fails

- Ensure message format matches exactly
- Confirm public key corresponds to address
- Check MintGarden API is operational
- Verify signature encoding (hex)

### "No Public Key" Error

- Some wallets don't expose pubkey via WalletConnect
- Public key is optional for verification
- Signature verification works without it

## Examples

### Simple Verification Bot

```javascript
// Clawdbot skill handler

const { verifySignature } = require('./lib/verify');

// /verify command
if (message.text === '/verify') {
  await message({
    action: 'send',
    target: message.chat.id,
    message: 'Verify your Chia wallet:',
    buttons: [[{
      text: '🌱 Connect Wallet',
      web_app: { url: process.env.WEB_APP_URL }
    }]]
  });
}

// Handle web app data
bot.on('web_app_data', async (msg) => {
  const { address, message: challengeMsg, signature, publicKey } = 
    JSON.parse(msg.web_app_data.data);
  
  const result = await verifySignature(address, challengeMsg, signature, publicKey);
  
  if (result.verified) {
    // Grant access
    await grantAccess(msg.from.id, address);
    await message({
      action: 'send',
      target: msg.chat.id,
      message: `✅ Verified! Welcome, ${address.substring(0, 12)}...`
    });
  } else {
    await message({
      action: 'send',
      target: msg.chat.id,
      message: `❌ Verification failed`
    });
  }
});
```

### NFT Gating

```javascript
// Check if user owns specific NFT collection

const { verifySignature } = require('./skills/chia-walletconnect/lib/verify');
const mintGarden = require('./skills/mintgarden'); // Assume mintgarden skill exists

bot.on('web_app_data', async (msg) => {
  const { address, message, signature, publicKey } = 
    JSON.parse(msg.web_app_data.data);
  
  // Verify signature first
  const verifyResult = await verifySignature(address, message, signature, publicKey);
  
  if (!verifyResult.verified) {
    return bot.sendMessage(msg.chat.id, '❌ Invalid signature');
  }
  
  // Check NFT ownership
  const nfts = await mintGarden.getNFTsByAddress(address);
  const hasRequiredNFT = nfts.some(nft => 
    nft.collection_id === 'col1required...'
  );
  
  if (hasRequiredNFT) {
    // Grant access to private group
    await inviteToGroup(msg.from.id);
    bot.sendMessage(msg.chat.id, '✅ Access granted! Check your invites.');
  } else {
    bot.sendMessage(msg.chat.id, '❌ You need a Wojak NFT to join!');
  }
});
```

## Performance

| Stage | Time |
|-------|------|
| WalletConnect Init | ~1-2s |
| Connection Approval | User action |
| Sign Request | ~2-5s |
| MintGarden Verify | ~0.5-1s |
| **Total** | **~5-10s** |

## Dependencies

- `@walletconnect/sign-client` — WalletConnect v2
- `@walletconnect/utils` — WalletConnect helpers
- `@walletconnect/types` — TypeScript types
- `express` — Web server
- `node-fetch` — HTTP client
- `cors` — CORS middleware
- `dotenv` — Environment config

## Version

1.0.0

## License

MIT — Koba42 Corp

## Links

- **MintGarden API:** https://api.mintgarden.io/docs
- **WalletConnect:** https://docs.walletconnect.com/
- **Telegram Web Apps:** https://core.telegram.org/bots/webapps
- **Sage Wallet:** https://www.sagewallet.io/
- **CHIP-0002:** https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0002.md

---

**Built with 🌱 by Koba42 Corp**