@botparty/sdk
Client SDK for BotParty — federated bot identity, authentication, and payments.
Zero config. One function. Your bot gets an identity, rotates its keys, and authenticates on any BotParty-compatible server automatically.
Install
npm install @botparty/sdk
Quick Start
import { botpartyFetch } from '@botparty/sdk';
const res = await botpartyFetch('https://api.example.com/data');
const data = await res.json();
On first run, the SDK:
- Generates an Ed25519 keypair
- Registers a namespace like
brave-fox-a3f2 on the BotParty server
- Stores the identity in
~/.botparty/
On every call, it:
- Checks if the key is about to go stale → auto-rotates
- Signs a JWT with the namespace identity
- Sends the request with
Authorization: Bearer <jwt>
Error Handling
BotParty-compatible servers return typed errors that the SDK catches and throws as specific error classes. Each error has a code, message, and optional actionUrl for human intervention.
import {
botpartyFetch,
NamespaceLockedError,
PaymentRequiredError,
InsufficientPermissionError,
LinkRequiredError,
} from '@botparty/sdk';
try {
const res = await botpartyFetch('https://api.example.com/data');
} catch (err) {
if (err instanceof NamespaceLockedError) {
console.log('Namespace locked! Human must unlock at:', err.actionUrl);
}
if (err instanceof PaymentRequiredError) {
console.log('Payment needed:', err.message, err.actionUrl);
}
if (err instanceof InsufficientPermissionError) {
console.log('Missing scopes:', err.missingScopes);
}
if (err instanceof LinkRequiredError) {
console.log('Link a human account at:', err.actionUrl);
}
}
Advanced Usage
Use BotPartyClient for full control over registration, key management, and namespace operations.
import { BotPartyClient } from '@botparty/sdk';
const client = new BotPartyClient({
serverUrl: 'https://id.botparty.club',
algorithm: 'EdDSA',
rotationTTL: 15,
});
await client.register('my-cool-bot', 'My Cool Bot');
await client.ensureRegistered();
const token = await client.generateToken();
const res = await client.fetch('https://api.example.com/data');
const me = client.whoami();
Key Management
const keys = await client.keys.list();
await client.keys.add({
publicKey: '-----BEGIN PUBLIC KEY-----\n...',
scopes: ['mongo://production/*:read'],
rotationTTL: 60,
});
await client.keys.rotateCurrent();
const key = client.key('key_abc123');
await key.info();
await key.update({ label: 'Updated label' });
await key.invalidate('Suspected compromise');
await key.delete();
Namespace Operations
const info = await client.info();
const { url } = await client.link();
console.log('Share this with your human:', url);
await client.destroy();
client.reset();
Configuration
serverUrl | BOTPARTY_SERVER_URL | https://id.botparty.club | BotParty server URL |
stateDir | BOTPARTY_STATE_DIR | ~/.botparty | Local state directory |
algorithm | — | EdDSA | Key algorithm (EdDSA or ES256) |
rotationTTL | — | 15 | Key rotation TTL in minutes |
State Files
The SDK stores identity and keys in ~/.botparty/:
~/.botparty/
├── identity.json # namespace, keyId, algorithm, rotatedAt, etc.
└── private.pem # Ed25519/EC private key (mode 0600)
Error Classes
BotPartyError | varies | varies | Base error class |
NamespaceLockedError | NAMESPACE_LOCKED | 423 | Namespace locked, human must unlock |
PaymentRequiredError | PAYMENT_REQUIRED | 402 | Payment needed for this action |
InsufficientPermissionError | INSUFFICIENT_PERMISSION | 403 | Missing required scopes |
LinkRequiredError | LINK_REQUIRED | 403 | Must link a human account |
All errors have .code, .message, .statusCode, and .actionUrl (when applicable).
License
MIT