Package Exports
- wa-auth-store
Readme
wa-auth-store
A TypeScript library for managing and synchronizing WhatsApp Baileys credentials between Redis (cache/in-memory store) and a persistent database using MikroORM.
Inspired by the useRedisAuthState pattern, this library provides a reusable, production-ready solution for storing Baileys authentication state with both fast Redis caching and database persistence.
Features
- Fast Access: Store Baileys credentials in Redis for quick retrieval
- Persistent Storage: Sync credentials to a database (PostgreSQL, MySQL, SQLite, etc.) via MikroORM
- Hybrid Approach: Prefer Redis, fall back to database, automatic cache warming
- Baileys-Optimized: Handle both
credsandkeys(SignalDataTypeMap) efficiently - Type-Safe: Full TypeScript support with strict type checking
- TTL Support: Automatic expiration of credentials in Redis
- Extensible: Easy to add support for other ORM adapters or databases
Installation
Default Installation
npm install wa-auth-storeThis automatically installs:
ioredis- Redis client@mikro-orm/core- ORM framework
Optional: Choose Your Database Driver
By default, no specific database driver is installed. Choose one based on your database:
For PostgreSQL:
npm install @mikro-orm/postgresqlFor MySQL:
npm install @mikro-orm/mysqlFor SQLite:
npm install @mikro-orm/sqliteSummary
| Package | Installed | Why |
|---|---|---|
wa-auth-store |
Auto | The library itself |
ioredis |
Auto | Redis operations (required) |
@mikro-orm/core |
Auto | Database ORM (required) |
@mikro-orm/postgresql |
Optional | PostgreSQL driver |
@mikro-orm/mysql |
Optional | MySQL driver |
@mikro-orm/sqlite |
Optional | SQLite driver |
Quick Start
Easiest: Use the Baileys Helper
The simplest way to integrate with Baileys - just pass the state directly:
import {
BaileysAuthStore,
BaileysRedisAdapter,
BaileysOrmAdapter,
useBaileysAuthState,
} from 'wa-auth-store';
import { makeWASocket } from '@whiskeysockets/baileys';
// Setup
const redisAdapter = new BaileysRedisAdapter('redis://localhost:6379');
await redisAdapter.connect();
const ormAdapter = new BaileysOrmAdapter(orm.em, CredentialsEntity);
const authStore = new BaileysAuthStore(redisAdapter, ormAdapter);
// Get ready-to-use state
const { state, saveCreds } = await useBaileysAuthState(authStore, 'session-123');
// Pass to Baileys - that's it!
const { socket } = makeWASocket({
auth: state,
printQRInTerminal: true,
});
// Save when credentials update
socket.ev.on('creds.update', saveCreds);Manual Usage with Redis Only
import { BaileysAuthStore, BaileysRedisAdapter } from 'wa-auth-store';
// Initialize Redis adapter
const redisAdapter = new BaileysRedisAdapter('redis://localhost:6379');
await redisAdapter.connect();
// Create auth store (Redis only)
const authStore = new BaileysAuthStore(redisAdapter);
// Save Baileys credentials
await authStore.saveCreds('session-123', {
creds: authenticationCreds, // Your Baileys AuthenticationCreds
keys: signalDataMap, // Your SignalDataTypeMap
});
// Retrieve credentials
const credential = await authStore.getCreds('session-123');
console.log(credential);
// Get specific keys
const appStateKeys = await authStore.getKeys('session-123', 'app-state-sync-key', [
'key-id-1',
'key-id-2',
]);
// Delete session
await authStore.deleteCreds('session-123');With PostgreSQL Persistence (MikroORM)
import { MikroORM } from '@mikro-orm/postgresql';
import { BaileysAuthStore, BaileysRedisAdapter, BaileysOrmAdapter } from 'wa-auth-store';
import { CredentialsEntity } from './entities/credentials.entity';
// Initialize MikroORM
const orm = await MikroORM.init({
entities: [CredentialsEntity],
dbName: 'baileys_db',
user: 'postgres',
password: 'password',
host: 'localhost',
});
// Initialize adapters
const redisAdapter = new BaileysRedisAdapter('redis://localhost:6379');
await redisAdapter.connect();
const ormAdapter = new BaileysOrmAdapter(orm.em, CredentialsEntity);
// Create auth store with both adapters
const authStore = new BaileysAuthStore(redisAdapter, ormAdapter);
// Save credentials (syncs to both Redis and PostgreSQL)
await authStore.saveCreds(
'session-123',
{
creds: authenticationCreds,
keys: signalDataMap,
},
{
syncToDatabase: true,
ttl: 3600, // 1 hour TTL in Redis
}
);
// Retrieve - prefers Redis, falls back to database
const credential = await authStore.getCreds('session-123');
// Cleanup
await redisAdapter.disconnect();
await orm.close();Integration with Baileys
import { useWhatsAppWeb } from '@whiskeysockets/baileys';
import { BaileysAuthStore, BaileysRedisAdapter, BaileysOrmAdapter } from 'wa-auth-store';
const redisAdapter = new BaileysRedisAdapter();
await redisAdapter.connect();
const ormAdapter = new BaileysOrmAdapter(orm.em, CredentialsEntity);
const authStore = new BaileysAuthStore(redisAdapter, ormAdapter);
const { state, saveCreds } = useWhatsAppWeb({
auth: {
creds: (await authStore.getCreds('session-id'))?.creds,
keys: {
get: async (type, ids) => {
return authStore.getKeys('session-id', type, ids);
},
set: async (data) => {
await authStore.setKeys('session-id', data);
},
},
},
});
// Override saveCreds to use our store
const originalSaveCreds = saveCreds;
saveCreds = async () => {
await authStore.saveCreds('session-id', {
creds: state.creds,
keys: state.keys,
});
};API Reference
useBaileysAuthState (Recommended for Baileys)
The easiest way to integrate with Baileys. Returns a complete authentication state with automatic credential and key management.
const { state, saveCreds } = await useBaileysAuthState(authStore, sessionId, options?);Parameters:
authStore(BaileysAuthStore) - Initialized auth storesessionId(string) - Unique session identifieroptions(optional):ttl?: number- Redis TTL in secondssyncToDatabase?: boolean- Sync to database (default: true)
Returns:
{
state: AuthenticationState, // Ready for Baileys
saveCreds: () => Promise<void> // Call on creds.update
}Example:
const { state, saveCreds } = await useBaileysAuthState(authStore, 'session-123');
const { socket } = makeWASocket({ auth: state });
socket.ev.on('creds.update', saveCreds);BaileysAuthStore
getCreds(sessionId)
Get credentials - prefers Redis, falls back to database.
- sessionId (string): Session identifier
- Returns: Promise<Partial
| null>
saveCreds(sessionId, credential, options?)
Save credentials to both Redis and database.
- sessionId (string): Session identifier
- credential (Partial
): Credential data with credsand/orkeys - options (optional):
{ syncToDatabase?: boolean, ttl?: number } - Returns: Promise
deleteCreds(sessionId)
Delete credentials from both Redis and database.
- sessionId (string): Session identifier
- Returns: Promise
getKeys(sessionId, type, ids)
Get specific keys - prefers Redis, falls back to database.
- sessionId (string): Session identifier
- type (string): Key type (e.g., 'app-state-sync-key', 'pre-key')
- ids (string[]): Key IDs to retrieve
- Returns: Promise<Record<string, unknown>>
setKeys(sessionId, data)
Set keys in both Redis and database.
- sessionId (string): Session identifier
- data (Record<string, Record<string, unknown>>): Keys organized by type
- Returns: Promise
deleteKeys(sessionId, fields)
Delete specific keys from both Redis and database.
- sessionId (string): Session identifier
- fields (string[]): Field names to delete
- Returns: Promise
clearSession(sessionId)
Clear all data for a session.
- sessionId (string): Session identifier
- Returns: Promise
Creating a Credentials Entity
Example MikroORM entity for PostgreSQL:
import { Entity, PrimaryKey, Property, Index, Unique } from '@mikro-orm/core';
@Entity()
export class CredentialsEntity {
@PrimaryKey()
id!: number;
@Property()
@Unique()
@Index()
sessionId!: string;
@Property({ type: 'jsonb', nullable: true })
creds?: unknown; // Baileys AuthenticationCreds
@Property({ type: 'jsonb', nullable: true })
keys?: Record<string, unknown>; // SignalDataTypeMap entries
@Property()
createdAt = new Date();
@Property({ onUpdate: () => new Date() })
updatedAt = new Date();
}Creating Custom ORM Adapters
To add support for a different ORM or database, extend the BaileysOrmAdapter class:
import { BaileysOrmAdapter } from 'wa-auth-store';
import type { BaileysCredential } from 'wa-auth-store';
export class CustomOrmAdapter extends BaileysOrmAdapter {
// Inherit all methods from BaileysOrmAdapter
// Customize as needed for your ORM
}Development
Setup
npm installCommands
npm run dev: Run in watch modenpm run build: Build for productionnpm run test: Run testsnpm run lint: Lint codenpm run lint:fix: Fix linting issuesnpm run format: Format code with Prettier
Testing
npm run test
npm run test:ui # Open UI dashboardLicense
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.