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:
- Connect their Sage Wallet via WalletConnect v2
- Sign a challenge message cryptographically
- Verify wallet ownership via MintGarden's signature verification API
- 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
# 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):
cd skills/chia-walletconnect/webapp
vercel
# Copy the URL (e.g., https://chia-verify.vercel.app)
Netlify:
cd skills/chia-walletconnect/webapp
netlify deploy --prod
Your Server:
# Start Express server
npm start
# Expose via ngrok or reverse proxy
Step 2: Register with BotFather
- Message @BotFather
- Send
/newappor/editapp - Select your bot
- Web App URL: Enter deployed URL
- Short Name:
verify
Step 3: Add to Bot
Using Clawdbot Message Tool
// 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
// 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:
# 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
{
"address": "xch1abc...",
"message": "Verify ownership of Chia wallet:...",
"signature": "hex_signature",
"pubkey": "hex_public_key"
}
Response:
{
"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:
PORT=3000
WALLETCONNECT_PROJECT_ID=your-project-id
MINTGARDEN_API_URL=https://api.mintgarden.io
Get WalletConnect Project ID
- Visit WalletConnect Cloud
- Create a new project
- Copy your Project ID
- 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
- Store verifications securely — Use encrypted database
- Rate limit — Prevent spam verification attempts
- Link to Telegram user ID — Prevent address spoofing
- Implement cooldown — 1 verification per user per day
- 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
// 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
// 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 typesexpress— Web servernode-fetch— HTTP clientcors— CORS middlewaredotenv— 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