chia-walletconnect

Web & Frontend Development
v1.0.0
Benign

Telegram Web App for Chia wallet verification via WalletConnect and Sage.

11.3K downloads1.3K installsby @koba42corp

Setup & Installation

Install command

clawhub install koba42corp/chia-walletconnect

If the CLI is not installed:

Install command

npx clawhub@latest install koba42corp/chia-walletconnect

Or install with OpenClaw CLI:

Install command

openclaw skills install koba42corp/chia-walletconnect

or paste the repo link into your assistant's chat

Install command

https://github.com/openclaw/skills/tree/main/skills/koba42corp/chia-walletconnect

What This Skill Does

A Telegram Mini App that lets users prove Chia wallet ownership without leaving Telegram. It connects Sage Wallet via WalletConnect v2, requests a signed challenge message, and confirms ownership through MintGarden's signature verification API.

The entire verification flow happens inside Telegram without redirecting users to an external site or requesting private keys.

When to Use It

  • Gating a Telegram group to verified Chia NFT holders
  • Running an airdrop where eligibility requires proof of wallet ownership
  • Authenticating DAO members before allowing votes
  • Verifying token holdings before granting access to private channels
  • Collecting cryptographic proof of wallet ownership during onboarding
View original SKILL.md file
# 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**

Example Workflow

Here's how your AI assistant might use this skill in practice.

INPUT

User asks: Gating a Telegram group to verified Chia NFT holders

AGENT
  1. 1Gating a Telegram group to verified Chia NFT holders
  2. 2Running an airdrop where eligibility requires proof of wallet ownership
  3. 3Authenticating DAO members before allowing votes
  4. 4Verifying token holdings before granting access to private channels
  5. 5Collecting cryptographic proof of wallet ownership during onboarding
OUTPUT
Telegram Web App for Chia wallet verification via WalletConnect and Sage.

Share this skill

Security Audits

VirusTotalBenign
OpenClawBenign
View full report

These signals reflect official OpenClaw status values. A Suspicious status means the skill should be used with extra caution.

Details

LanguageMarkdown
Last updatedFeb 26, 2026