@quantumapi/sdk
v0.1.0-beta.0
Published
Official TypeScript SDK for QuantumAPI - Post-Quantum Cryptography Platform
Maintainers
Readme
@quantumapi/sdk
Official TypeScript SDK for QuantumAPI - Post-Quantum Cryptography Platform
Overview
QuantumAPI provides post-quantum cryptography as a service, enabling developers to future-proof their applications against quantum computing threats. This SDK provides a type-safe, idiomatic TypeScript interface to the QuantumAPI platform.
Features
- 🔐 Post-Quantum Cryptography - ML-KEM-768, ML-DSA-65 support
- 🔑 Key Management - Generate, rotate, and manage cryptographic keys
- 🗄️ Secret Vault - Secure secret storage with versioning
- 👥 User Management - OIDC-based identity and access management
- 📊 Audit Logs - Complete audit trail of all operations
- 🔄 Automatic Retries - Exponential backoff for transient failures
- ⚡ TypeScript First - Full type safety with strict mode
- 🌐 Universal - Works in Node.js 18+ and modern browsers
- 📦 Tree-shakeable - ESM and CJS builds
Installation
npm install @quantumapi/sdkOr with yarn:
yarn add @quantumapi/sdkQuick Start
import { QuantumAPIClient } from '@quantumapi/sdk';
// Initialize the client
const client = new QuantumAPIClient({
apiKey: 'qapi_xxx',
// Optional: specify custom base URL
// baseUrl: 'https://api.quantumapi.eu/api/v1'
});
// Encrypt data using post-quantum cryptography
const encrypted = await client.encryption.encrypt({
plaintext: 'Hello, quantum-safe world!',
});
console.log('Ciphertext:', encrypted.ciphertext);
// Decrypt data
const decrypted = await client.encryption.decrypt({
encryptedPayload: encrypted.encryptedPayload,
});
console.log('Plaintext:', decrypted.plaintext);Core Modules
Encryption Client
// Encrypt data
const result = await client.encryption.encrypt({
plaintext: 'secret data',
keyId: '550e8400-e29b-41d4-a716-446655440000', // Optional: use specific key
encoding: 'utf8',
});
// Decrypt data
const decrypted = await client.encryption.decrypt({
encryptedPayload: result.encryptedPayload,
});
// Sign a message
const signature = await client.encryption.sign({
message: 'Important message',
keyId: 'signing-key-id',
});
// Verify a signature
const verified = await client.encryption.verify({
message: 'Important message',
signature: signature.signature,
keyId: 'signing-key-id',
});Keys Client
// Generate a new key pair
const key = await client.keys.generate({
name: 'my-encryption-key',
algorithm: 'ML-KEM-768',
purpose: 'encryption',
labels: { env: 'production' },
});
// List all keys
const keys = await client.keys.list({
purpose: 'encryption',
status: 'active',
page: 1,
pageSize: 20,
});
// Get a specific key
const keyDetails = await client.keys.get(key.id);
// Rotate a key
const newKey = await client.keys.rotate({
keyId: key.id,
newKeyName: 'my-encryption-key-v2',
});
// Delete a key
await client.keys.delete(key.id);
// Generate a data key for envelope encryption
const dataKey = await client.keys.generateDataKey({
keyId: key.id,
keySpec: 'AES-256',
});Secrets Client
// Create a secret
const secret = await client.secrets.create({
name: 'database-password',
value: 'super-secret-password',
type: 'database_credential',
labels: { env: 'production', app: 'api' },
metadata: { database: 'postgres', host: 'db.example.com' },
});
// List secrets
const secrets = await client.secrets.list({
type: 'api_key',
labels: 'env=production',
page: 1,
pageSize: 20,
});
// Get a secret
const retrievedSecret = await client.secrets.get(secret.id);
// Update a secret (creates new version)
const updated = await client.secrets.update(secret.id, {
value: 'new-password',
});
// List versions
const versions = await client.secrets.listVersions(secret.id);
// Create a shared link
const link = await client.secrets.createSharedLink({
secretId: secret.id,
expiresAt: '2024-12-31T23:59:59Z',
maxAccessCount: 5,
});
console.log('Share URL:', link.url);
// Bulk export
const exported = await client.secrets.bulkExport();
// Bulk import
await client.secrets.bulkImport(exported.exportData, exported.exportKey);Users Client
// Create a user
const user = await client.users.create({
email: '[email protected]',
name: 'John Developer',
roles: ['developer'],
});
// List users
const users = await client.users.list({
status: 'active',
page: 1,
});
// Update a user
const updated = await client.users.update(user.id, {
name: 'John Senior Developer',
roles: ['developer', 'admin'],
});
// Deactivate a user
await client.users.deactivate(user.id);Applications Client
// Create an OAuth/OIDC application
const app = await client.applications.create({
name: 'My Web App',
redirectUris: ['https://app.example.com/callback'],
scopes: ['openid', 'profile', 'email'],
});
console.log('Client ID:', app.clientId);
console.log('Client Secret:', app.clientSecret);
// List applications
const apps = await client.applications.list();
// Rotate client secret
const rotated = await client.applications.rotateSecret(app.id);
console.log('New secret:', rotated.clientSecret);Audit Client
// Query audit logs
const logs = await client.audit.query({
startDate: '2024-01-01T00:00:00Z',
endDate: '2024-12-31T23:59:59Z',
action: 'encrypt',
status: 'success',
page: 1,
pageSize: 50,
});
logs.items.forEach(log => {
console.log(`${log.timestamp}: ${log.action} by ${log.userId}`);
});
// Export audit logs
const exportUrl = await client.audit.export({
startDate: '2024-01-01T00:00:00Z',
endDate: '2024-12-31T23:59:59Z',
});Billing Client
// Get current subscription
const subscription = await client.billing.getSubscription();
console.log('Plan:', subscription.plan);
console.log('Status:', subscription.status);
// Get usage metrics
const usage = await client.billing.getUsage();
console.log('API calls:', usage.apiCalls);
console.log('Total cost:', usage.costs.total);
// List invoices
const invoices = await client.billing.listInvoices();
// Get billing portal URL
const portal = await client.billing.getPortalUrl();
console.log('Manage billing:', portal.url);Health Client
// Check API health
const health = await client.health.getStatus();
console.log('Status:', health.status);
console.log('Version:', health.version);
// Get rate limit info
const rateLimit = await client.health.getRateLimit();
console.log('Remaining:', rateLimit.remaining, '/', rateLimit.limit);Error Handling
The SDK provides typed error classes for common error scenarios:
import {
QuantumAPIError,
RateLimitError,
AuthenticationError,
AuthorizationError,
NotFoundError,
ValidationError,
NetworkError,
} from '@quantumapi/sdk';
try {
await client.encryption.encrypt({ plaintext: 'test' });
} catch (error) {
if (error instanceof RateLimitError) {
console.log('Rate limit exceeded, retry after:', error.retryAfter);
} else if (error instanceof AuthenticationError) {
console.log('Invalid API key');
} else if (error instanceof AuthorizationError) {
console.log('Insufficient permissions');
} else if (error instanceof NotFoundError) {
console.log('Resource not found');
} else if (error instanceof ValidationError) {
console.log('Validation failed:', error.details);
} else if (error instanceof NetworkError) {
console.log('Network error:', error.message);
} else if (error instanceof QuantumAPIError) {
console.log('API error:', error.status, error.message);
}
}Configuration
Client Options
const client = new QuantumAPIClient({
// Required: Your API key
apiKey: 'qapi_xxx',
// Optional: Custom base URL (default: https://api.quantumapi.eu/api/v1)
baseUrl: 'https://api.quantumapi.eu/api/v1',
// Optional: Request timeout in milliseconds (default: 30000)
timeout: 30000,
// Optional: Maximum number of retries (default: 3)
maxRetries: 3,
// Optional: Tenant ID (for multi-tenant scenarios)
tenantId: 'my-tenant-id',
});Automatic Retries
The SDK automatically retries failed requests with exponential backoff for:
- Network errors
- 429 Rate Limit errors
- 5xx Server errors
Non-retryable errors (4xx except 429) fail immediately.
Type Safety
All request and response types are fully typed:
import type {
EncryptRequest,
EncryptResponse,
CryptoKey,
Secret,
User,
CryptoAlgorithm,
KeyPurpose,
} from '@quantumapi/sdk';
// TypeScript will catch type errors
const request: EncryptRequest = {
plaintext: 'test',
algorithm: 'ML-KEM-768', // Type-safe algorithm selection
};
const response: EncryptResponse = await client.encryption.encrypt(request);Runtime Validation
The SDK uses Zod for runtime validation of requests:
// This will throw a ValidationError before making the API call
await client.keys.generate({
name: '', // Error: name must be at least 1 character
algorithm: 'INVALID', // Error: invalid algorithm
purpose: 'encryption',
});Browser Support
The SDK works in modern browsers (ES2020+) and Node.js 18+:
<script type="module">
import { QuantumAPIClient } from '@quantumapi/sdk';
const client = new QuantumAPIClient({ apiKey: 'qapi_xxx' });
const result = await client.encryption.encrypt({
plaintext: 'Browser encryption!',
});
console.log(result);
</script>React Integration
For React applications, use the @quantumapi/react package (sold separately):
import { QuantumAPIProvider, useEncrypt } from '@quantumapi/react';
function App() {
return (
<QuantumAPIProvider apiKey="qapi_xxx">
<MyComponent />
</QuantumAPIProvider>
);
}
function MyComponent() {
const { encrypt, isLoading, error } = useEncrypt();
const handleEncrypt = async () => {
const result = await encrypt({ plaintext: 'test' });
console.log(result);
};
return <button onClick={handleEncrypt}>Encrypt</button>;
}Next.js Integration
For Next.js applications, use the @quantumapi/next package (sold separately):
// pages/api/encrypt.ts
import { createEncryptionHandler } from '@quantumapi/next';
export default createEncryptionHandler({
apiKey: process.env.QUANTUMAPI_KEY!,
});Contributing
We welcome contributions! Please see CONTRIBUTING.md for details.
License
MIT License - see LICENSE for details.
Support
- 📧 Email: [email protected]
- 💬 Discord: https://discord.gg/quantumapi
- 📖 Documentation: https://docs.quantumapi.eu
- 🐛 Issues: https://github.com/quantumapi/sdk-typescript/issues
Security
For security vulnerabilities, please email [email protected] instead of opening an issue.
Changelog
See CHANGELOG.md for release history.
