
Credentials
- 14 installs
- 610 repo stars
- Updated June 26, 2026
- alsk1992/cloddsbot
Credentials is a skill that securely stores and manages trading-platform API keys using AES-256-GCM encryption with per-user isolation and failure cooldowns.
About
Credentials is a skill for securely storing and managing API keys for trading platforms with AES-256-GCM encryption. A developer adds, lists, tests and removes credentials per platform, and the skill applies cooldowns after failed auth attempts. It matters as the shared secrets layer for the other trading skills in this toolkit.
- Securely store trading-platform API credentials with AES-256-GCM encryption
- Add, test and remove creds for Polymarket, Kalshi, Binance, Bybit and more
- Per-user isolation, failure cooldowns and no secret logging
Credentials by the numbers
- 14 all-time installs (skills.sh)
- Ranked #1,623 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
credentials capabilities & compatibility
- Capabilities
- binance futures · bybit futures · crypto hft
- Works with
- postgres
- Use cases
- security audit
- Pricing
- Bring your own API key
What credentials says it does
Securely store and manage API credentials for trading platforms with AES-256-GCM encryption.
**AES-256-GCM** | Military-grade encryption at rest
npx skills add https://github.com/alsk1992/cloddsbot --skill credentialsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 14 |
|---|---|
| repo stars | ★ 610 |
| Last updated | June 26, 2026 |
| Repository | alsk1992/cloddsbot ↗ |
What it does
Encrypt, store, test and rotate API credentials for multiple trading platforms with per-user isolation.
Who is it for?
Encrypting and rotating API keys for the trading skills in this toolkit
When should I use this skill?
You need to store, test or rotate trading-platform API credentials securely
By the numbers
- 8 supported platforms
- AES-256-GCM encryption
- default 15-minute cooldown after 3 failures
Files
Credentials - Complete API Reference
Securely store and manage API credentials for trading platforms with AES-256-GCM encryption.
---
Chat Commands
Add Credentials
/creds add polymarket Interactive setup
/creds add kalshi --key abc --secret xyz Direct setup
/creds add binance Add Binance API
/creds add hyperliquid Add wallet keyView Credentials
/creds list List configured platforms
/creds status Encryption system status
/creds test polymarket Test API connection
/creds check polymarket Verify credentials workRemove Credentials
/creds remove polymarket Remove platform creds
/creds clear Clear all (careful!)Auth Status
/auth status Overall auth status
/auth refresh kalshi Refresh tokens
/auth cooldown View cooldown status---
TypeScript API Reference
Create Credentials Manager
import { createCredentialsManager } from 'clodds/credentials';
const creds = createCredentialsManager({
// Encryption key (required)
encryptionKey: process.env.CREDENTIALS_KEY,
// Storage backend
storage: 'sqlite', // 'sqlite' | 'postgres'
dbPath: './credentials.db',
// Cooldown settings
cooldownMinutes: 15,
maxFailures: 3,
});Set Credentials
// Polymarket (API + signing key)
await creds.setCredentials({
userId: 'user-123',
platform: 'polymarket',
credentials: {
apiKey: 'pk_...',
apiSecret: 'sk_...',
privateKey: '0x...', // For order signing
funderAddress: '0x...',
},
});
// Kalshi (API key)
await creds.setCredentials({
userId: 'user-123',
platform: 'kalshi',
credentials: {
email: 'user@example.com',
apiKey: 'key_...',
},
});
// Binance Futures
await creds.setCredentials({
userId: 'user-123',
platform: 'binance',
credentials: {
apiKey: 'abc...',
apiSecret: 'xyz...',
},
});
// Hyperliquid (wallet)
await creds.setCredentials({
userId: 'user-123',
platform: 'hyperliquid',
credentials: {
privateKey: '0x...',
walletAddress: '0x...',
},
});Get Credentials
// Get for specific platform
const polymarketCreds = await creds.getCredentials({
userId: 'user-123',
platform: 'polymarket',
});
if (polymarketCreds) {
console.log(`API Key: ${polymarketCreds.apiKey}`);
// Credentials are decrypted on retrieval
}
// List user's configured platforms
const platforms = await creds.listUserPlatforms('user-123');
console.log(`Configured: ${platforms.join(', ')}`);Delete Credentials
// Remove single platform
await creds.deleteCredentials({
userId: 'user-123',
platform: 'kalshi',
});
// Remove all for user
await creds.deleteAllCredentials('user-123');Test Credentials
// Test API connection
const result = await creds.testCredentials({
userId: 'user-123',
platform: 'polymarket',
});
if (result.success) {
console.log(`✓ Connected to ${result.platform}`);
console.log(` Balance: $${result.balance}`);
} else {
console.log(`✗ Failed: ${result.error}`);
}Cooldown Management
// Mark failed auth attempt
await creds.markFailure({
userId: 'user-123',
platform: 'kalshi',
error: 'Invalid API key',
});
// Check if in cooldown
const inCooldown = await creds.isInCooldown({
userId: 'user-123',
platform: 'kalshi',
});
if (inCooldown) {
const remaining = await creds.getCooldownRemaining({
userId: 'user-123',
platform: 'kalshi',
});
console.log(`Cooldown: ${remaining} minutes remaining`);
}
// Mark successful auth (resets failures)
await creds.markSuccess({
userId: 'user-123',
platform: 'kalshi',
});Build Trading Context
// Get ready-to-use trading context
const context = await creds.buildTradingContext({
userId: 'user-123',
platform: 'polymarket',
});
// Context includes authenticated client
await context.client.getBalance();
await context.client.placeOrder({ ... });---
Supported Platforms
| Platform | Credentials Required |
|---|---|
| Polymarket | API key, secret, private key, funder address |
| Kalshi | Email, API key |
| Betfair | App key, session token |
| Smarkets | API key |
| Binance | API key, secret |
| Bybit | API key, secret |
| Hyperliquid | Private key, wallet address |
| MEXC | API key, secret |
---
Security Features
| Feature | Description |
|---|---|
| AES-256-GCM | Military-grade encryption at rest |
| Per-user keys | Isolated credential storage |
| Cooldown | Rate limits on failed attempts |
| No logging | Secrets never logged |
| Memory wipe | Credentials cleared from memory after use |
---
Environment Variables
# Required encryption key (generate with: openssl rand -hex 32)
CREDENTIALS_KEY=your-64-char-hex-key
# Optional: per-platform keys
POLYMARKET_API_KEY=pk_...
POLYMARKET_API_SECRET=sk_...
POLYMARKET_PRIVATE_KEY=0x...
KALSHI_EMAIL=user@example.com
KALSHI_API_KEY=key_...---
Best Practices
1. Strong encryption key — Use openssl rand -hex 32 2. Rotate keys regularly — Update API keys periodically 3. Test after adding — Always verify credentials work 4. Minimal permissions — Use read-only keys when possible 5. Backup securely — Keep encrypted backups offline
/**
* Credentials CLI Skill
*
* Commands:
* /creds list - List stored credentials
* /creds set <platform> <key> <value> - Set credential
* /creds delete <platform> - Delete credentials
* /creds check <platform> - Verify credentials work
*/
async function execute(args: string): Promise<string> {
const parts = args.trim().split(/\s+/);
const cmd = parts[0]?.toLowerCase() || 'help';
try {
const credPath = ['..', '..', '..', 'credentials', 'index'].join('/');
const dbPath = ['..', '..', '..', 'db', 'index'].join('/');
const { createCredentialsManager } = await import(credPath);
const { createDatabase } = await import(dbPath);
const db = createDatabase();
const manager = createCredentialsManager(db);
const userId = 'default';
switch (cmd) {
case 'list':
case 'ls': {
const platforms = ['polymarket', 'kalshi', 'manifold'] as const;
let output = '**Stored Credentials**\n\n| Platform | Status |\n|----------|--------|\n';
for (const platform of platforms) {
const has = await manager.hasCredentials(userId, platform);
output += `| ${platform} | ${has ? 'Configured' : 'Not set'} |\n`;
}
// Also check env vars for additional platforms
output += `| Binance | ${process.env.BINANCE_API_KEY ? 'Configured (env)' : 'Not set'} |\n`;
output += `| Bybit | ${process.env.BYBIT_API_KEY ? 'Configured (env)' : 'Not set'} |\n`;
output += `| Hyperliquid | ${process.env.HYPERLIQUID_API_KEY ? 'Configured (env)' : 'Not set'} |\n`;
return output;
}
case 'set':
case 'add': {
if (parts.length < 4) return 'Usage: /creds set <platform> <key> <value>\n\nPlatforms: polymarket, kalshi, manifold\nKeys vary by platform (api_key, api_secret, api_passphrase, etc.)';
const platform = parts[1].toLowerCase();
const validPlatforms = ['polymarket', 'kalshi', 'manifold', 'binance', 'bybit', 'hyperliquid', 'drift'];
if (!validPlatforms.includes(platform)) {
return `Unknown platform "${platform}". Supported: ${validPlatforms.join(', ')}`;
}
const key = parts[2];
const value = parts[3];
// Build credentials object from key-value
const existing = (await manager.getCredentials(userId, platform as any) || {}) as Record<string, string>;
const updated = { ...existing, [key]: value };
await manager.setCredentials(userId, platform as any, updated as any);
return `Credential **${key}** set for **${platform}** (encrypted with AES-256-GCM).`;
}
case 'delete':
case 'remove': {
if (!parts[1]) return 'Usage: /creds delete <platform>';
const platform = parts[1].toLowerCase();
await manager.deleteCredentials(userId, platform as any);
return `Credentials for **${platform}** deleted.`;
}
case 'check':
case 'verify':
case 'test': {
if (!parts[1]) return 'Usage: /creds check <platform>';
const platform = parts[1].toLowerCase();
const has = await manager.hasCredentials(userId, platform as any);
if (!has) return `No credentials stored for **${platform}**. Use \`/creds set\` first.`;
const creds = await manager.getCredentials(userId, platform as any);
if (creds) {
await manager.markSuccess(userId, platform as any);
return `Credentials for **${platform}** are stored and decryptable.`;
}
return `Failed to decrypt credentials for **${platform}**. They may be corrupted.`;
}
case 'clear': {
const platforms = await manager.listUserPlatforms(userId);
if (platforms.length === 0) {
return 'No credentials stored. Nothing to clear.';
}
for (const platform of platforms) {
await manager.deleteCredentials(userId, platform);
}
return `Cleared credentials for ${platforms.length} platform(s): ${platforms.join(', ')}.`;
}
case 'status': {
const hasKey = Boolean(process.env.CLODDS_CREDENTIAL_KEY);
return `**Credential System Status**\n\n` +
`Encryption key: ${hasKey ? 'Set (CLODDS_CREDENTIAL_KEY)' : 'NOT SET - credentials cannot be encrypted'}\n` +
`Algorithm: AES-256-GCM\n` +
`Storage: SQLite (encrypted at rest)`;
}
default:
return helpText();
}
} catch (error) {
return `Credentials error: ${error instanceof Error ? error.message : String(error)}`;
}
}
function helpText(): string {
return `**Credentials Commands**
/creds list - List stored credentials
/creds set <platform> <key> <value> - Set credential (encrypted)
/creds delete <platform> - Delete credentials
/creds clear - Clear all stored credentials
/creds check <platform> - Verify credentials work
/creds status - Encryption system status
**Platforms:** polymarket, kalshi, manifold
Credentials encrypted with AES-256-GCM. Set CLODDS_CREDENTIAL_KEY env var.`;
}
export default {
name: 'credentials',
description: 'Secure credential management for trading platforms',
commands: ['/creds', '/credentials'],
handle: execute,
};