@atpkeyserver/client Examples#
This directory contains examples demonstrating how to use the ATP Keyserver client library.
Available Examples#
basic-usage.ts#
A comprehensive example showing all major features of the library:
- Crypto Functions Only - Direct encrypt/decrypt without keyserver
- KeyserverClient Encryption - Full flow with service auth
- KeyserverClient Decryption - Retrieving and decrypting content
- Error Handling - Proper error handling for all error types
- Cache Management - Understanding and managing the cache
- Batch Decryption - Processing multiple encrypted posts efficiently
Prerequisites#
Node.js#
Requires Node.js 22+ or Bun:
node --version # Should be v22.0.0 or higher
Dependencies#
The example requires these packages:
# In the client directory
cd packages/client
# Install dependencies
bun install # or npm install
Required packages:
@atpkeyserver/client(this library)@atproto/api(for PDS integration)
Running the Example#
Using Bun (Recommended)#
bun run examples/basic-usage.ts
Using Node.js#
First, build the library:
npm run build
Then run with tsx or ts-node:
npx tsx examples/basic-usage.ts
Expected Output#
The example will run through all 6 examples sequentially, demonstrating:
- ✅ Successful crypto operations
- ⚠️ Expected failures in mock environment (keyserver not running)
- 📖 Educational comments about each operation
- 🎨 Colored output showing success/error states
Note: Examples 2-6 use mock data and will show expected errors since no actual keyserver is running. This is intentional and demonstrates error handling.
Adapting for Production#
To use in production, replace mock values with real ones:
1. Authenticate with PDS#
const agent = new AtpAgent({ service: 'https://bsky.social' })
await agent.login({
identifier: 'your-handle.bsky.social',
password: 'your-app-password'
})
2. Use Real Keyserver#
const keyserver = new KeyserverClient({
keyserverDid: 'did:web:your-keyserver.com', // Real keyserver DID
getServiceAuthToken: async (aud, lxm) => {
const { data } = await agent.com.atproto.server.getServiceAuth({
aud,
lxm,
exp: Math.floor(Date.now() / 1000) + 60
})
return data.token
}
})
3. Store/Retrieve Real Posts#
Replace mock data with actual PDS operations:
// Create encrypted post
const record = await agent.com.atproto.repo.putRecord({
repo: agent.session.did,
collection: 'app.bsky.feed.post',
record: {
encrypted_content: ciphertext,
key_version: version,
encrypted_at: new Date().toISOString(),
visibility: 'followers'
}
})
// Retrieve and decrypt
const post = await agent.getPost(postUri)
const plaintext = await keyserver.decrypt(
postUri,
groupId,
post.encrypted_content,
post.key_version
)
Understanding the Output#
Successful Operations#
✅ Crypto round-trip successful!
✅ Encrypted successfully!
These indicate operations completed without errors.
Expected Errors (Mock Environment)#
❌ Decryption failed (expected in mock environment)
Since no real keyserver is running, these errors are expected and demonstrate proper error handling.
Error Types Demonstrated#
The examples show how to handle:
- 🚫 ForbiddenError - User lost access
- 🔍 NotFoundError - Resource deleted
- 🔐 DecryptionError - Cannot decrypt (permanent)
- 🌐 NetworkError - Temporary network issue (can retry)
Common Issues#
Import Errors#
If you see module resolution errors:
# Ensure library is built
bun run build
# Check TypeScript paths are correct
cat tsconfig.json
Runtime Errors#
If crypto operations fail:
- Ensure Node.js 22+ (native crypto support)
- Check that
@noble/ciphersis installed - Verify hex-encoded keys are exactly 64 characters
Next Steps#
After understanding the examples:
- Read ../README.md for complete API reference
- Review ../../docs/ENCRYPTION_PROTOCOL.md for protocol details
- Check ../../docs/SECURITY.md for security best practices
- Build your application using the patterns demonstrated
Questions?#
- Open an issue: https://codeberg.org/juandjara/atp-keyserver/issues
- Read the docs: ../../docs/