@zervonex/baileys 3.0.5 → 3.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -25
- package/lib/Utils/use-multi-file-auth-state.js +44 -69
- package/lib/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -350,15 +350,14 @@ Two adapters are available. They do **not** share an identical return shape —
|
|
|
350
350
|
|
|
351
351
|
### File-based (default)
|
|
352
352
|
|
|
353
|
-
Atomic writes
|
|
353
|
+
Atomic writes (tmp → rename with fallback), corrupt file self-healing, and automatic old pre-key cleanup. Best for single-instance bots or local development.
|
|
354
354
|
|
|
355
355
|
```javascript
|
|
356
356
|
import { useMultiFileAuthState } from '@zervonex/baileys'
|
|
357
357
|
|
|
358
358
|
const { state, saveCreds, getStats } = await useMultiFileAuthState('auth_session', {
|
|
359
|
-
preKeyRetention:
|
|
360
|
-
cleanupThreshold:
|
|
361
|
-
logger, // optional — logs checksum mismatches and cleanup events
|
|
359
|
+
preKeyRetention: 150, // how many recent prekeys to keep (default: 150)
|
|
360
|
+
cleanupThreshold: 50, // new prekeys before a cleanup runs (default: 50)
|
|
362
361
|
})
|
|
363
362
|
|
|
364
363
|
const sock = makeWASocket({ auth: state })
|
|
@@ -369,15 +368,20 @@ const stats = await getStats()
|
|
|
369
368
|
// { totalFiles: 42, preKeyCount: 150, nextPreKeyId: 3200, lastCleanupAt: '2026-07-05T...' }
|
|
370
369
|
```
|
|
371
370
|
|
|
372
|
-
To fully log out and delete a session
|
|
371
|
+
To fully log out and delete a session, remove the session folder directly — there is no `clearSession` method on this adapter:
|
|
372
|
+
|
|
373
|
+
```javascript
|
|
374
|
+
import { rm } from 'fs/promises'
|
|
375
|
+
await rm('auth_session', { recursive: true, force: true })
|
|
376
|
+
```
|
|
373
377
|
|
|
374
378
|
### Keyv-based (production)
|
|
375
379
|
|
|
376
|
-
Universal adapter for any database backend via [Keyv](https://
|
|
380
|
+
Universal adapter for any database backend via [Keyv](https://www.npmjs.com/package/keyv). Pass a connection string — the matching backend driver is resolved and cached automatically, no manual adapter imports needed.
|
|
377
381
|
|
|
378
|
-
|
|
382
|
+
Both adapters use the same `BufferJSON` serialization format and auto-detect legacy `{ value: { value: ... } }` double-wrapping from older versions — no manual data migration needed when upgrading.
|
|
379
383
|
|
|
380
|
-
The first argument is the **session ID** — equivalent to the folder name in `useMultiFileAuthState`. It
|
|
384
|
+
The first argument is the **session ID** — equivalent to the folder name in `useMultiFileAuthState`. It is used as a Keyv namespace so multiple bots can safely share one backend without key collisions. The second argument is a connection string, a pre-built `Keyv` instance, or a raw `KeyvStoreAdapter`:
|
|
381
385
|
|
|
382
386
|
```javascript
|
|
383
387
|
import { useKeyvAuthState } from '@zervonex/baileys'
|
|
@@ -407,52 +411,56 @@ const { state, saveCreds } = await useKeyvAuthState('bot1', 'memcache://localhos
|
|
|
407
411
|
const { state, saveCreds } = await useKeyvAuthState('test')
|
|
408
412
|
```
|
|
409
413
|
|
|
410
|
-
Supported
|
|
414
|
+
Supported protocols: `redis:`/`rediss:`, `mongodb:`/`mongodb+srv:`, `postgres:`/`postgresql:`, `mysql:`, `sqlite:`, `etcd:`, `memcache:`/`memcached:`. All matching driver packages ship as dependencies — nothing extra to install.
|
|
411
415
|
|
|
412
|
-
For backends without a connection string (e.g. DynamoDB), or to
|
|
416
|
+
For backends without a connection string (e.g. DynamoDB), or to share one connection across multiple sessions, pass a pre-built adapter or `Keyv` instance:
|
|
413
417
|
|
|
414
418
|
```javascript
|
|
415
|
-
import { useKeyvAuthState } from '@zervonex/baileys'
|
|
416
419
|
import KeyvMongo from '@keyv/mongo'
|
|
420
|
+
import KeyvDynamo from '@keyv/dynamo'
|
|
421
|
+
|
|
422
|
+
// share one connection across sessions
|
|
423
|
+
const mongo = new KeyvMongo('mongodb://localhost/baileys')
|
|
424
|
+
const { state: s1 } = await useKeyvAuthState('bot1', mongo)
|
|
425
|
+
const { state: s2 } = await useKeyvAuthState('bot2', mongo)
|
|
417
426
|
|
|
418
|
-
|
|
419
|
-
const
|
|
427
|
+
// DynamoDB (no connection string protocol)
|
|
428
|
+
const dynamo = new KeyvDynamo({ region: 'us-east-1', table: 'baileys_auth' })
|
|
429
|
+
const { state, saveCreds } = await useKeyvAuthState('bot1', dynamo)
|
|
420
430
|
```
|
|
421
431
|
|
|
422
|
-
|
|
432
|
+
Connection strings passed as plain strings are automatically cached and reused across every `useKeyvAuthState` call in the process — no need to build the instance yourself just to avoid duplicate connections.
|
|
423
433
|
|
|
424
|
-
By default, Mongo/Postgres/MySQL/SQLite store everything in a collection/table named `keyv
|
|
434
|
+
By default, Mongo/Postgres/MySQL/SQLite store everything in a collection/table named `keyv`. Pass `collectionName` to use your own:
|
|
425
435
|
|
|
426
436
|
```javascript
|
|
427
437
|
const { state, saveCreds } = await useKeyvAuthState('bot1', 'mongodb://localhost/baileys', {
|
|
428
|
-
collectionName: 'baileys_auth',
|
|
438
|
+
collectionName: 'baileys_auth',
|
|
429
439
|
})
|
|
430
440
|
```
|
|
431
441
|
|
|
432
|
-
> Per-type backend routing (e.g. prekeys on SQLite, sessions on Postgres) is not currently supported — one `useKeyvAuthState` call uses one backend for
|
|
442
|
+
> Per-type backend routing (e.g. prekeys on SQLite, sessions on Postgres) is not currently supported — one `useKeyvAuthState` call uses one backend for all key types.
|
|
433
443
|
|
|
434
444
|
#### Clearing a session (logout)
|
|
435
445
|
|
|
436
446
|
```javascript
|
|
437
447
|
const { state, saveCreds, clearSession } = await useKeyvAuthState('bot1', 'redis://localhost:6379')
|
|
438
448
|
|
|
439
|
-
|
|
440
|
-
await clearSession()
|
|
449
|
+
await clearSession() // wipes all keys for this session, disconnects the store
|
|
441
450
|
```
|
|
442
451
|
|
|
443
|
-
`clearSession()`
|
|
452
|
+
`clearSession()` removes every key scoped to that session's namespace — creds, prekeys, sessions, sender keys, everything. Other sessions sharing the same backend are untouched.
|
|
444
453
|
|
|
445
454
|
#### Checking auth without loading full state
|
|
446
455
|
|
|
447
456
|
```javascript
|
|
448
457
|
import { hasKeyvAuth } from '@zervonex/baileys'
|
|
449
458
|
|
|
450
|
-
// Check if a session has valid auth (lightweight — no full state load)
|
|
451
459
|
const valid = await hasKeyvAuth('bot1', backend)
|
|
452
460
|
// true if creds exist and contain noiseKey + signedIdentityKey
|
|
453
461
|
```
|
|
454
462
|
|
|
455
|
-
|
|
463
|
+
Lightweight — opens no full auth state, just checks for valid creds under the session's namespace.
|
|
456
464
|
|
|
457
465
|
#### Options
|
|
458
466
|
|
|
@@ -460,8 +468,7 @@ const valid = await hasKeyvAuth('bot1', backend)
|
|
|
460
468
|
|--------|------|---------|-------------|
|
|
461
469
|
| `preKeyRetention` | `number` | `150` | Number of recent prekeys to keep |
|
|
462
470
|
| `cleanupThreshold` | `number` | `50` | New prekeys generated before cleanup runs |
|
|
463
|
-
| `
|
|
464
|
-
| `collectionName` | `string` | adapter's own default (`"keyv"`) | Custom collection/table name — Keyv-based adapter only, ignored for connection-string-less (in-memory) and pre-built adapter/`Keyv` instances |
|
|
471
|
+
| `collectionName` | `string` | `"keyv"` | Custom collection/table name (Keyv adapter only, ignored for in-memory and pre-built instances) |
|
|
465
472
|
|
|
466
473
|
#### Return values
|
|
467
474
|
|
|
@@ -471,7 +478,6 @@ const valid = await hasKeyvAuth('bot1', backend)
|
|
|
471
478
|
| `saveCreds` | ✅ | ✅ |
|
|
472
479
|
| `getStats` | ✅ | ❌ |
|
|
473
480
|
| `clearSession` | ❌ (delete the folder instead) | ✅ |
|
|
474
|
-
| `close` | ❌ | ✅ (drops local listeners; safe to call, does not disconnect a shared backend) |
|
|
475
481
|
|
|
476
482
|
---
|
|
477
483
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdir, readFile, rename, stat, unlink, writeFile, readdir } from 'fs/promises'
|
|
2
2
|
import { join } from 'path'
|
|
3
|
-
import { Keyv } from 'keyv'
|
|
3
|
+
import { Keyv, detectKeyvStorage } from 'keyv'
|
|
4
4
|
import { proto } from '../../WAProto/index.js'
|
|
5
5
|
import { initAuthCreds } from './auth-utils.js'
|
|
6
6
|
import { BufferJSON } from './generics.js'
|
|
@@ -11,21 +11,16 @@ const DEFAULT_PREKEY_RETENTION = 150
|
|
|
11
11
|
const DEFAULT_CLEANUP_THRESHOLD = 50
|
|
12
12
|
const CLEANUP_INTERVAL_MS = 10 * 60 * 1000
|
|
13
13
|
|
|
14
|
-
// ──
|
|
14
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
15
15
|
|
|
16
16
|
const bootstrapCreds = raw => raw ?? initAuthCreds()
|
|
17
|
-
|
|
18
|
-
const patchAppStateKey = (type, v) =>
|
|
19
|
-
type === 'app-state-sync-key' && v ? proto.Message.AppStateSyncKeyData.fromObject(v) : v
|
|
20
|
-
|
|
17
|
+
const patchAppStateKey = (type, v) => type === 'app-state-sync-key' && v ? proto.Message.AppStateSyncKeyData.fromObject(v) : v
|
|
21
18
|
const ser = v => v == null ? null : JSON.parse(JSON.stringify(v, BufferJSON.replacer))
|
|
22
|
-
|
|
23
19
|
const deser = raw => {
|
|
24
20
|
if (raw == null) return null
|
|
25
21
|
let p = typeof raw === 'string'
|
|
26
|
-
? (() => { try { return JSON.parse(raw) } catch (e) { logger.warn({ err: e.message }, '[Auth] failed to parse stored value
|
|
22
|
+
? (() => { try { return JSON.parse(raw) } catch (e) { logger.warn({ err: e.message }, '[Auth] failed to parse stored value'); return null } })()
|
|
27
23
|
: raw
|
|
28
|
-
// unwrap adapter double-wrapping e.g. { value: { value: actual } }
|
|
29
24
|
while (p && typeof p === 'object' && !Array.isArray(p) && Object.keys(p).length === 1 && 'value' in p) p = p.value
|
|
30
25
|
if (p == null) return null
|
|
31
26
|
if (typeof p === 'object' && '__checksum' in p && 'data' in p) p = p.data
|
|
@@ -34,7 +29,9 @@ const deser = raw => {
|
|
|
34
29
|
|
|
35
30
|
// ── Adapter resolution ────────────────────────────────────────────────────────
|
|
36
31
|
|
|
32
|
+
// Only adapters that accept a named collection/table — redis, valkey, etcd, memcache, dynamo do not
|
|
37
33
|
const COLLECTION_KEY = { '@keyv/mongo': 'collection', '@keyv/postgres': 'table', '@keyv/mysql': 'table', '@keyv/sqlite': 'table' }
|
|
34
|
+
|
|
38
35
|
const _adapterCache = new Map()
|
|
39
36
|
export const clearAdapterCache = () => _adapterCache.clear()
|
|
40
37
|
|
|
@@ -44,7 +41,7 @@ const resolveAdapter = async (conn, col) => {
|
|
|
44
41
|
let protocol
|
|
45
42
|
try { protocol = new URL(conn).protocol } catch { throw new Error(`[Auth] Invalid connection string: "${conn}"`) }
|
|
46
43
|
const pkg = PROTOCOL_ADAPTERS[protocol]
|
|
47
|
-
if (!pkg) throw new Error(`[Auth] Unsupported protocol "${protocol}" — supported:
|
|
44
|
+
if (!pkg) throw new Error(`[Auth] Unsupported protocol "${protocol}" — supported: ${Object.keys(PROTOCOL_ADAPTERS).map(p => p.replace(':', '')).join(', ')}`)
|
|
48
45
|
let mod
|
|
49
46
|
try { mod = await import(pkg) } catch (e) {
|
|
50
47
|
if (e.code === 'ERR_MODULE_NOT_FOUND') throw new Error(`[Auth] "${pkg}" required — npm i ${pkg}`)
|
|
@@ -58,12 +55,25 @@ const resolveAdapter = async (conn, col) => {
|
|
|
58
55
|
return adapter
|
|
59
56
|
}
|
|
60
57
|
|
|
61
|
-
|
|
58
|
+
// Object.create scoping only needed for mapLike stores — keyvStorage and asyncMap have namespace managed by Keyv/bridge
|
|
59
|
+
const resolveStore = async (backend, col, namespace) => {
|
|
62
60
|
if (backend == null) return null
|
|
63
61
|
if (typeof backend === 'string') return resolveAdapter(backend, col)
|
|
64
62
|
if (backend instanceof Keyv) return backend.opts?.store ?? backend.store ?? null
|
|
65
|
-
|
|
66
|
-
throw new Error('[Auth] backend must be a connection string, Keyv instance, or KeyvStoreAdapter')
|
|
63
|
+
const { compatible, store } = detectKeyvStorage(backend)
|
|
64
|
+
if (!compatible) throw new Error('[Auth] backend must be a connection string, Keyv instance, or KeyvStoreAdapter')
|
|
65
|
+
if (store === 'mapLike') {
|
|
66
|
+
const scoped = Object.create(backend)
|
|
67
|
+
if (namespace) scoped.namespace = namespace
|
|
68
|
+
return scoped
|
|
69
|
+
}
|
|
70
|
+
return backend
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const makeKeyv = (store, namespace) => {
|
|
74
|
+
const keyv = store ? new Keyv({ store, namespace }) : new Keyv({ namespace })
|
|
75
|
+
keyv.setMaxListeners?.(0)
|
|
76
|
+
return keyv
|
|
67
77
|
}
|
|
68
78
|
|
|
69
79
|
// ── File-based auth state ─────────────────────────────────────────────────────
|
|
@@ -77,13 +87,12 @@ export const useMultiFileAuthState = async (folder, opts = {}) => {
|
|
|
77
87
|
if (info) { if (!info.isDirectory()) throw new Error(`Not a directory: ${folder}`) }
|
|
78
88
|
else await mkdir(folder, { recursive: true })
|
|
79
89
|
|
|
80
|
-
//
|
|
90
|
+
// Atomic write: tmp → rename, fallback to direct write
|
|
81
91
|
const write = async (data, file) => {
|
|
82
92
|
const [p, t, payload] = [fp(file), fp(file) + '.tmp', JSON.stringify(data, BufferJSON.replacer)]
|
|
83
93
|
await writeFile(t, payload)
|
|
84
94
|
try { await rename(t, p) } catch { await writeFile(p, payload); await unlink(t).catch(() => { }) }
|
|
85
95
|
}
|
|
86
|
-
|
|
87
96
|
const read = async file => {
|
|
88
97
|
const raw = await readFile(fp(file), 'utf-8').catch(() => null)
|
|
89
98
|
if (!raw) return null
|
|
@@ -96,7 +105,6 @@ export const useMultiFileAuthState = async (folder, opts = {}) => {
|
|
|
96
105
|
return null
|
|
97
106
|
}
|
|
98
107
|
}
|
|
99
|
-
|
|
100
108
|
const remove = f => unlink(fp(f)).catch(() => { })
|
|
101
109
|
|
|
102
110
|
let creds = bootstrapCreds(await read('creds.json'))
|
|
@@ -114,11 +122,9 @@ export const useMultiFileAuthState = async (folder, opts = {}) => {
|
|
|
114
122
|
.map(m => join(folder, m[0]))
|
|
115
123
|
if (targets.length) await Promise.all(targets.map(f => unlink(f).catch(() => { })))
|
|
116
124
|
lastCleanupAt = Date.now(); lastCleanedId = creds.nextPreKeyId
|
|
117
|
-
} catch (e) {
|
|
118
|
-
|
|
119
|
-
} finally { cleanupRunning = false }
|
|
125
|
+
} catch (e) { logger.warn({ err: e.message }, 'prekey cleanup failed') }
|
|
126
|
+
finally { cleanupRunning = false }
|
|
120
127
|
}
|
|
121
|
-
|
|
122
128
|
cleanOldPreKeys().catch(() => { })
|
|
123
129
|
|
|
124
130
|
return {
|
|
@@ -153,20 +159,14 @@ export const useMultiFileAuthState = async (folder, opts = {}) => {
|
|
|
153
159
|
|
|
154
160
|
export const useKeyvAuthState = async (sessionId, backend, opts = {}) => {
|
|
155
161
|
const { preKeyRetention = DEFAULT_PREKEY_RETENTION, cleanupThreshold = DEFAULT_CLEANUP_THRESHOLD, collectionName } = opts
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
const keyv = store ? new Keyv({ store }) : new Keyv()
|
|
159
|
-
keyv.setMaxListeners?.(0)
|
|
162
|
+
const store = await resolveStore(backend, collectionName, sessionId)
|
|
163
|
+
const keyv = makeKeyv(store, sessionId)
|
|
160
164
|
keyv.on('error', err => logger.warn({ err: err?.message, sessionId }, '[Auth] store error'))
|
|
161
165
|
|
|
162
|
-
|
|
163
|
-
const
|
|
164
|
-
const credsKey = `${sessionId}::creds`
|
|
165
|
-
|
|
166
|
+
const kn = (type, id) => `${type}-${id}`
|
|
167
|
+
const credsKey = 'creds'
|
|
166
168
|
let creds = bootstrapCreds(deser(await keyv.get(credsKey)))
|
|
167
169
|
let cleanupRunning = false, lastCleanupAt = 0, lastCleanedId = creds.nextPreKeyId
|
|
168
|
-
// tracks every key ever written — fallback clearSession uses this to wipe all types including JID-based IDs
|
|
169
|
-
const _writtenKeys = new Set([credsKey])
|
|
170
170
|
|
|
171
171
|
const cleanOldPreKeys = async () => {
|
|
172
172
|
if (cleanupRunning || Date.now() - lastCleanupAt < CLEANUP_INTERVAL_MS) return
|
|
@@ -176,13 +176,11 @@ export const useKeyvAuthState = async (sessionId, backend, opts = {}) => {
|
|
|
176
176
|
if (minId <= 0) return
|
|
177
177
|
const ids = []
|
|
178
178
|
for (let id = Math.max(0, lastCleanedId - preKeyRetention); id < minId; id++) ids.push(kn('pre-key', id))
|
|
179
|
-
if (ids.length) await
|
|
179
|
+
if (ids.length) await keyv.deleteMany(ids)
|
|
180
180
|
lastCleanupAt = Date.now(); lastCleanedId = creds.nextPreKeyId
|
|
181
|
-
} catch (e) {
|
|
182
|
-
|
|
183
|
-
} finally { cleanupRunning = false }
|
|
181
|
+
} catch (e) { logger.warn({ err: e.message, sessionId }, '[Auth] prekey cleanup failed') }
|
|
182
|
+
finally { cleanupRunning = false }
|
|
184
183
|
}
|
|
185
|
-
|
|
186
184
|
cleanOldPreKeys().catch(() => { })
|
|
187
185
|
|
|
188
186
|
const keys = {
|
|
@@ -196,58 +194,35 @@ export const useKeyvAuthState = async (sessionId, backend, opts = {}) => {
|
|
|
196
194
|
for (const type in data)
|
|
197
195
|
for (const id in data[type]) {
|
|
198
196
|
const v = data[type][id], k = kn(type, id)
|
|
199
|
-
if (v != null)
|
|
200
|
-
else
|
|
197
|
+
if (v != null) sets.push({ key: k, value: ser(v) })
|
|
198
|
+
else dels.push(k)
|
|
201
199
|
}
|
|
202
|
-
await Promise.all([
|
|
203
|
-
sets.length ? keyv.setMany(sets) : null,
|
|
204
|
-
dels.length ? keyv.deleteMany(dels) : null
|
|
205
|
-
])
|
|
200
|
+
await Promise.all([sets.length ? keyv.setMany(sets) : null, dels.length ? keyv.deleteMany(dels) : null])
|
|
206
201
|
}
|
|
207
202
|
}
|
|
208
203
|
|
|
209
204
|
const saveCreds = async () => {
|
|
210
205
|
if (creds.nextPreKeyId - lastCleanedId >= cleanupThreshold) cleanOldPreKeys().catch(() => { })
|
|
211
|
-
_writtenKeys.add(credsKey)
|
|
212
206
|
await keyv.set(credsKey, ser(creds))
|
|
213
207
|
}
|
|
214
208
|
|
|
215
209
|
const clearSession = async () => {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (rc && typeof rc.keys === 'function') {
|
|
222
|
-
try { await store.set('__probe__', 1); const m = await rc.keys(`${prefix}*`); if (m.length) await rc.del(m); done = true } catch { }
|
|
223
|
-
}
|
|
224
|
-
// Mongo/Postgres/SQLite: iterator scan
|
|
225
|
-
if (!done && typeof store.iterator === 'function') {
|
|
226
|
-
try {
|
|
227
|
-
const targets = []
|
|
228
|
-
for await (const [k] of store.iterator(prefix)) if (k.startsWith(prefix)) targets.push(k)
|
|
229
|
-
if (targets.length) await store.deleteMany(targets)
|
|
230
|
-
done = true
|
|
231
|
-
} catch { }
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
if (!done) {
|
|
235
|
-
// fallback (in-memory): delete every key ever written — covers all types + JID-based IDs
|
|
236
|
-
await Promise.all([..._writtenKeys].map(k => keyv.delete(k).catch(() => { })))
|
|
237
|
-
_writtenKeys.clear()
|
|
238
|
-
}
|
|
210
|
+
try {
|
|
211
|
+
const isolated = makeKeyv(store, sessionId)
|
|
212
|
+
await isolated.clear()
|
|
213
|
+
isolated.removeAllListeners?.()
|
|
214
|
+
} catch (e) { logger.warn({ err: e.message, sessionId }, '[Auth] clearSession failed') }
|
|
239
215
|
keyv.removeAllListeners?.()
|
|
240
216
|
}
|
|
241
217
|
|
|
242
218
|
return { state: { creds, keys }, saveCreds, clearSession }
|
|
243
219
|
}
|
|
244
220
|
|
|
245
|
-
//
|
|
221
|
+
// Checks if valid creds exist for a session without fully loading it
|
|
246
222
|
export const hasKeyvAuth = async (sessionId, backend, opts = {}) => {
|
|
247
223
|
try {
|
|
248
|
-
const
|
|
249
|
-
const
|
|
250
|
-
const parsed = deser(await keyv.get(`${sessionId}::creds`))
|
|
224
|
+
const keyv = makeKeyv(await resolveStore(backend, opts.collectionName, sessionId), sessionId)
|
|
225
|
+
const parsed = deser(await keyv.get('creds'))
|
|
251
226
|
return !!(parsed?.noiseKey && parsed?.signedIdentityKey)
|
|
252
227
|
} catch { return false }
|
|
253
228
|
}
|
package/lib/index.js
CHANGED
|
@@ -29,7 +29,7 @@ const info = [
|
|
|
29
29
|
'╭──────────────────────────────────────────────────────────────╮',
|
|
30
30
|
'│ │',
|
|
31
31
|
'│ ◆ Package › @zervonex/baileys │',
|
|
32
|
-
'│ ◆ Version › 3.0.
|
|
32
|
+
'│ ◆ Version › 3.0.7 │',
|
|
33
33
|
'│ ◆ Status › Production Ready │',
|
|
34
34
|
'│ │',
|
|
35
35
|
'├──────────────────────────── ◇◆◇ ─────────────────────────────┤',
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@zervonex/baileys",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "3.0.
|
|
5
|
+
"version": "3.0.7",
|
|
6
6
|
"description": "Advanced WhatsApp Web API built on Baileys — interactive messages, buttons, carousels, products, events, payments, polls, albums, sticker packs and more.",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"baileys",
|