@vanzxy/baileys 2.0.0

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.
Files changed (281) hide show
  1. package/NOTICE.md +111 -0
  2. package/README.md +830 -0
  3. package/WAProto/index.d.ts +9 -0
  4. package/WAProto/index.js +142036 -0
  5. package/engine-requirements.js +13 -0
  6. package/lib/Defaults/index.d.ts +152 -0
  7. package/lib/Defaults/index.js +179 -0
  8. package/lib/Framework/Bot.js +209 -0
  9. package/lib/Framework/Context.js +90 -0
  10. package/lib/Framework/MediaManager.js +152 -0
  11. package/lib/Framework/SessionManager.js +34 -0
  12. package/lib/Framework/StatsManager.js +120 -0
  13. package/lib/Framework/Store/SQLiteStore.js +74 -0
  14. package/lib/Framework/index.js +11 -0
  15. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  16. package/lib/Signal/Group/ciphertext-message.js +12 -0
  17. package/lib/Signal/Group/group-session-builder.d.ts +7 -0
  18. package/lib/Signal/Group/group-session-builder.js +30 -0
  19. package/lib/Signal/Group/group_cipher.d.ts +10 -0
  20. package/lib/Signal/Group/group_cipher.js +82 -0
  21. package/lib/Signal/Group/index.d.ts +11 -0
  22. package/lib/Signal/Group/index.js +12 -0
  23. package/lib/Signal/Group/keyhelper.d.ts +6 -0
  24. package/lib/Signal/Group/keyhelper.js +18 -0
  25. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  26. package/lib/Signal/Group/sender-chain-key.js +26 -0
  27. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  28. package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
  29. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  30. package/lib/Signal/Group/sender-key-message.js +66 -0
  31. package/lib/Signal/Group/sender-key-name.d.ts +11 -0
  32. package/lib/Signal/Group/sender-key-name.js +48 -0
  33. package/lib/Signal/Group/sender-key-record.d.ts +12 -0
  34. package/lib/Signal/Group/sender-key-record.js +41 -0
  35. package/lib/Signal/Group/sender-key-state.d.ts +16 -0
  36. package/lib/Signal/Group/sender-key-state.js +84 -0
  37. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  38. package/lib/Signal/Group/sender-message-key.js +26 -0
  39. package/lib/Signal/libsignal.d.ts +54 -0
  40. package/lib/Signal/libsignal.js +431 -0
  41. package/lib/Signal/lid-mapping.d.ts +20 -0
  42. package/lib/Signal/lid-mapping.js +277 -0
  43. package/lib/Socket/Client/index.d.ts +2 -0
  44. package/lib/Socket/Client/index.js +3 -0
  45. package/lib/Socket/Client/types.d.ts +5 -0
  46. package/lib/Socket/Client/types.js +11 -0
  47. package/lib/Socket/Client/websocket.d.ts +12 -0
  48. package/lib/Socket/Client/websocket.js +54 -0
  49. package/lib/Socket/business.d.ts +395 -0
  50. package/lib/Socket/business.js +380 -0
  51. package/lib/Socket/chats.d.ts +136 -0
  52. package/lib/Socket/chats.js +1328 -0
  53. package/lib/Socket/communities.d.ts +561 -0
  54. package/lib/Socket/communities.js +434 -0
  55. package/lib/Socket/dugong.d.ts +117 -0
  56. package/lib/Socket/dugong.js +799 -0
  57. package/lib/Socket/groups.d.ts +285 -0
  58. package/lib/Socket/groups.js +355 -0
  59. package/lib/Socket/index.d.ts +531 -0
  60. package/lib/Socket/index.js +34 -0
  61. package/lib/Socket/messages-recv.d.ts +333 -0
  62. package/lib/Socket/messages-recv.js +1782 -0
  63. package/lib/Socket/messages-send.d.ts +329 -0
  64. package/lib/Socket/messages-send.js +1383 -0
  65. package/lib/Socket/mex.d.ts +1 -0
  66. package/lib/Socket/mex.js +42 -0
  67. package/lib/Socket/newsletter.d.ts +281 -0
  68. package/lib/Socket/newsletter.js +321 -0
  69. package/lib/Socket/socket.d.ts +60 -0
  70. package/lib/Socket/socket.js +1001 -0
  71. package/lib/Socket/username.js +153 -0
  72. package/lib/Store/index.d.ts +3 -0
  73. package/lib/Store/index.js +4 -0
  74. package/lib/Store/make-in-memory-store.d.ts +62 -0
  75. package/lib/Store/make-in-memory-store.js +429 -0
  76. package/lib/Store/make-ordered-dictionary.d.ts +12 -0
  77. package/lib/Store/make-ordered-dictionary.js +79 -0
  78. package/lib/Store/object-repository.d.ts +10 -0
  79. package/lib/Store/object-repository.js +24 -0
  80. package/lib/Types/Auth.d.ts +117 -0
  81. package/lib/Types/Auth.js +2 -0
  82. package/lib/Types/Bussines.d.ts +25 -0
  83. package/lib/Types/Bussines.js +2 -0
  84. package/lib/Types/Call.d.ts +15 -0
  85. package/lib/Types/Call.js +2 -0
  86. package/lib/Types/Chat.d.ts +124 -0
  87. package/lib/Types/Chat.js +8 -0
  88. package/lib/Types/Contact.d.ts +26 -0
  89. package/lib/Types/Contact.js +2 -0
  90. package/lib/Types/Events.d.ts +256 -0
  91. package/lib/Types/Events.js +2 -0
  92. package/lib/Types/GroupMetadata.d.ts +71 -0
  93. package/lib/Types/GroupMetadata.js +2 -0
  94. package/lib/Types/Label.d.ts +2 -0
  95. package/lib/Types/Label.js +25 -0
  96. package/lib/Types/LabelAssociation.d.ts +2 -0
  97. package/lib/Types/LabelAssociation.js +7 -0
  98. package/lib/Types/Message.d.ts +11 -0
  99. package/lib/Types/Message.js +18 -0
  100. package/lib/Types/Mex.d.ts +2 -0
  101. package/lib/Types/Mex.js +39 -0
  102. package/lib/Types/Product.d.ts +79 -0
  103. package/lib/Types/Product.js +2 -0
  104. package/lib/Types/RichType.d.ts +2 -0
  105. package/lib/Types/RichType.js +23 -0
  106. package/lib/Types/Signal.d.ts +87 -0
  107. package/lib/Types/Signal.js +2 -0
  108. package/lib/Types/Socket.d.ts +136 -0
  109. package/lib/Types/Socket.js +2 -0
  110. package/lib/Types/State.d.ts +5 -0
  111. package/lib/Types/State.js +56 -0
  112. package/lib/Types/USync.d.ts +26 -0
  113. package/lib/Types/USync.js +2 -0
  114. package/lib/Types/index.d.ts +66 -0
  115. package/lib/Types/index.js +26 -0
  116. package/lib/Utils/A2UI.js +277 -0
  117. package/lib/Utils/MessageBuilder.js +4405 -0
  118. package/lib/Utils/MessageBuilder_d.ts +411 -0
  119. package/lib/Utils/PersistentStore.js +592 -0
  120. package/lib/Utils/PersistentStore_d.ts +60 -0
  121. package/lib/Utils/anti-delete.d.ts +74 -0
  122. package/lib/Utils/anti-delete.js +222 -0
  123. package/lib/Utils/auth-utils.d.ts +57 -0
  124. package/lib/Utils/auth-utils.js +307 -0
  125. package/lib/Utils/auto-reply.d.ts +47 -0
  126. package/lib/Utils/auto-reply.js +158 -0
  127. package/lib/Utils/baileys-event-stream.d.ts +8 -0
  128. package/lib/Utils/baileys-event-stream.js +62 -0
  129. package/lib/Utils/browser-utils.d.ts +8 -0
  130. package/lib/Utils/browser-utils.js +28 -0
  131. package/lib/Utils/business.d.ts +49 -0
  132. package/lib/Utils/business.js +240 -0
  133. package/lib/Utils/button-helper-utils.js +314 -0
  134. package/lib/Utils/button-sender.js +824 -0
  135. package/lib/Utils/chat-control.d.ts +159 -0
  136. package/lib/Utils/chat-control.js +232 -0
  137. package/lib/Utils/chat-history-helpers.d.ts +21 -0
  138. package/lib/Utils/chat-history-helpers.js +71 -0
  139. package/lib/Utils/chat-utils.d.ts +407 -0
  140. package/lib/Utils/chat-utils.js +886 -0
  141. package/lib/Utils/companion-reg-client-utils.d.ts +4 -0
  142. package/lib/Utils/companion-reg-client-utils.js +40 -0
  143. package/lib/Utils/crypto.d.ts +41 -0
  144. package/lib/Utils/crypto.js +148 -0
  145. package/lib/Utils/decode-wa-message.d.ts +83 -0
  146. package/lib/Utils/decode-wa-message.js +317 -0
  147. package/lib/Utils/event-buffer.d.ts +12 -0
  148. package/lib/Utils/event-buffer.js +636 -0
  149. package/lib/Utils/generics.d.ts +69 -0
  150. package/lib/Utils/generics.js +439 -0
  151. package/lib/Utils/history.d.ts +90 -0
  152. package/lib/Utils/history.js +147 -0
  153. package/lib/Utils/identity-change-handler.d.ts +13 -0
  154. package/lib/Utils/identity-change-handler.js +50 -0
  155. package/lib/Utils/index.d.ts +39 -0
  156. package/lib/Utils/index.js +46 -0
  157. package/lib/Utils/link-preview.d.ts +12 -0
  158. package/lib/Utils/link-preview.js +85 -0
  159. package/lib/Utils/logger.d.ts +2 -0
  160. package/lib/Utils/logger.js +3 -0
  161. package/lib/Utils/lt-hash.d.ts +12 -0
  162. package/lib/Utils/lt-hash.js +27 -0
  163. package/lib/Utils/make-mutex.d.ts +6 -0
  164. package/lib/Utils/make-mutex.js +33 -0
  165. package/lib/Utils/media-messages.d.ts +18 -0
  166. package/lib/Utils/media-messages.js +71 -0
  167. package/lib/Utils/media-set.d.ts +13 -0
  168. package/lib/Utils/media-set.js +172 -0
  169. package/lib/Utils/message-kind.js +139 -0
  170. package/lib/Utils/message-retry-manager.d.ts +79 -0
  171. package/lib/Utils/message-retry-manager.js +265 -0
  172. package/lib/Utils/message-search.d.ts +44 -0
  173. package/lib/Utils/message-search.js +189 -0
  174. package/lib/Utils/messages-media.d.ts +135 -0
  175. package/lib/Utils/messages-media.js +869 -0
  176. package/lib/Utils/messages.d.ts +44 -0
  177. package/lib/Utils/messages.js +2155 -0
  178. package/lib/Utils/noise-handler.d.ts +20 -0
  179. package/lib/Utils/noise-handler.js +201 -0
  180. package/lib/Utils/offline-node-processor.d.ts +9 -0
  181. package/lib/Utils/offline-node-processor.js +40 -0
  182. package/lib/Utils/past-participants.d.ts +14 -0
  183. package/lib/Utils/past-participants.js +40 -0
  184. package/lib/Utils/pre-key-manager.d.ts +25 -0
  185. package/lib/Utils/pre-key-manager.js +106 -0
  186. package/lib/Utils/process-message.d.ts +82 -0
  187. package/lib/Utils/process-message.js +809 -0
  188. package/lib/Utils/reporting-utils.d.ts +12 -0
  189. package/lib/Utils/reporting-utils.js +258 -0
  190. package/lib/Utils/rich-message-utils.d.ts +48 -0
  191. package/lib/Utils/rich-message-utils.js +445 -0
  192. package/lib/Utils/scheduling.d.ts +42 -0
  193. package/lib/Utils/scheduling.js +140 -0
  194. package/lib/Utils/signal.d.ts +82 -0
  195. package/lib/Utils/signal.js +201 -0
  196. package/lib/Utils/stanza-ack.d.ts +16 -0
  197. package/lib/Utils/stanza-ack.js +38 -0
  198. package/lib/Utils/status.d.ts +50 -0
  199. package/lib/Utils/status.js +108 -0
  200. package/lib/Utils/stickerpack.d.ts +51 -0
  201. package/lib/Utils/stickerpack.js +275 -0
  202. package/lib/Utils/sync-action-utils.d.ts +2 -0
  203. package/lib/Utils/sync-action-utils.js +49 -0
  204. package/lib/Utils/tc-token-utils.d.ts +29 -0
  205. package/lib/Utils/tc-token-utils.js +163 -0
  206. package/lib/Utils/templates.d.ts +76 -0
  207. package/lib/Utils/templates.js +151 -0
  208. package/lib/Utils/use-cache-manager-auth-state.d.ts +13 -0
  209. package/lib/Utils/use-cache-manager-auth-state.js +82 -0
  210. package/lib/Utils/use-multi-file-auth-state.d.ts +10 -0
  211. package/lib/Utils/use-multi-file-auth-state.js +167 -0
  212. package/lib/Utils/use-single-file-auth-state.d.ts +10 -0
  213. package/lib/Utils/use-single-file-auth-state.js +114 -0
  214. package/lib/Utils/use-sqlite-auth-state.d.ts +11 -0
  215. package/lib/Utils/use-sqlite-auth-state.js +170 -0
  216. package/lib/Utils/validate-connection.d.ts +42 -0
  217. package/lib/Utils/validate-connection.js +199 -0
  218. package/lib/Utils/vcard.d.ts +58 -0
  219. package/lib/Utils/vcard.js +105 -0
  220. package/lib/VoIP/audio-feeder.d.ts +15 -0
  221. package/lib/VoIP/audio-feeder.js +132 -0
  222. package/lib/VoIP/index.js +277 -0
  223. package/lib/VoIP/relay-transport.d.ts +43 -0
  224. package/lib/VoIP/relay-transport.js +559 -0
  225. package/lib/VoIP/signaling.js +624 -0
  226. package/lib/VoIP/types.d.ts +69 -0
  227. package/lib/VoIP/types.js +17 -0
  228. package/lib/VoIP/wasm-engine.d.ts +103 -0
  229. package/lib/VoIP/wasm-engine.js +1214 -0
  230. package/lib/VoIP/worker-bootstrap.js +1042 -0
  231. package/lib/WABinary/constants.d.ts +61 -0
  232. package/lib/WABinary/constants.js +1467 -0
  233. package/lib/WABinary/decode.d.ts +9 -0
  234. package/lib/WABinary/decode.js +262 -0
  235. package/lib/WABinary/encode.d.ts +2 -0
  236. package/lib/WABinary/encode.js +220 -0
  237. package/lib/WABinary/generic-utils.d.ts +74 -0
  238. package/lib/WABinary/generic-utils.js +277 -0
  239. package/lib/WABinary/index.d.ts +5 -0
  240. package/lib/WABinary/index.js +6 -0
  241. package/lib/WABinary/jid-utils.d.ts +28 -0
  242. package/lib/WABinary/jid-utils.js +96 -0
  243. package/lib/WABinary/types.d.ts +19 -0
  244. package/lib/WABinary/types.js +2 -0
  245. package/lib/WAM/BinaryInfo.d.ts +7 -0
  246. package/lib/WAM/BinaryInfo.js +10 -0
  247. package/lib/WAM/constants.d.ts +34926 -0
  248. package/lib/WAM/constants.js +22853 -0
  249. package/lib/WAM/encode.d.ts +1 -0
  250. package/lib/WAM/encode.js +150 -0
  251. package/lib/WAM/index.d.ts +3 -0
  252. package/lib/WAM/index.js +4 -0
  253. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +36 -0
  254. package/lib/WAUSync/Protocols/USyncContactProtocol.js +52 -0
  255. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +29 -0
  256. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +63 -0
  257. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  258. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
  259. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  260. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +38 -0
  261. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +9 -0
  262. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
  263. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +38 -0
  264. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +51 -0
  265. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +14 -0
  266. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
  267. package/lib/WAUSync/Protocols/index.d.ts +7 -0
  268. package/lib/WAUSync/Protocols/index.js +8 -0
  269. package/lib/WAUSync/USyncQuery.d.ts +20 -0
  270. package/lib/WAUSync/USyncQuery.js +122 -0
  271. package/lib/WAUSync/USyncUser.d.ts +16 -0
  272. package/lib/WAUSync/USyncUser.js +31 -0
  273. package/lib/WAUSync/index.d.ts +3 -0
  274. package/lib/WAUSync/index.js +4 -0
  275. package/lib/assets/wasm/loader.js +5 -0
  276. package/lib/assets/wasm/whatsapp.wasm +0 -0
  277. package/lib/assets/wasm/worker-modules.js +273 -0
  278. package/lib/index.d.ts +12 -0
  279. package/lib/index.js +20 -0
  280. package/package.json +175 -0
  281. package/postinstall-banner.js +56 -0
@@ -0,0 +1,170 @@
1
+ import { mkdir, readFile, stat, unlink, writeFile } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import { proto } from '../../WAProto/index.js';
4
+ import { initAuthCreds } from './auth-utils.js';
5
+ import { BufferJSON } from './generics.js';
6
+ async function loadBetterSqlite3() {
7
+ try {
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ const mod = (await import('better-sqlite3'));
10
+ return mod.default ?? mod;
11
+ }
12
+ catch (err) {
13
+ const helpful = new Error('`better-sqlite3` is required for `useSqliteAuthState`. Install it as a peer dependency: `npm install better-sqlite3` (or `yarn add better-sqlite3`).');
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ helpful.cause = err;
16
+ throw helpful;
17
+ }
18
+ }
19
+ const CREDS_ROW_KEY = '__creds__';
20
+ const CREATE_SCHEMA_SQL = `
21
+ CREATE TABLE IF NOT EXISTS creds (
22
+ key TEXT PRIMARY KEY,
23
+ value TEXT NOT NULL
24
+ );
25
+ CREATE TABLE IF NOT EXISTS signal_keys (
26
+ type TEXT NOT NULL,
27
+ id TEXT NOT NULL,
28
+ value TEXT NOT NULL,
29
+ PRIMARY KEY (type, id)
30
+ );
31
+ CREATE INDEX IF NOT EXISTS signal_keys_type_idx ON signal_keys(type);
32
+ `;
33
+ // Vanz@Add 29-08-26 --- Migration tracking, ported in spirit from zapo-js's
34
+ // wa_migrations pattern (packages/store-sqlite/src/migrations.ts). Each entry
35
+ // is `{ id, sql }`; applied migrations are recorded by id in `wa_migrations`
36
+ // so `db.exec(...)` schema changes are only ever run once per database file,
37
+ // letting future releases evolve the schema without a manual ALTER step from
38
+ // the user. Kept as an ordered array (not a folder of files) since the schema
39
+ // here is a single flat file, unlike zapo's per-domain migration modules.
40
+ const MIGRATIONS = [
41
+ { id: '0001_init', sql: CREATE_SCHEMA_SQL }
42
+ ];
43
+ function ensureMigrationsTable(db) {
44
+ db.exec('CREATE TABLE IF NOT EXISTS wa_migrations (id TEXT PRIMARY KEY, applied_at INTEGER NOT NULL)');
45
+ }
46
+ function runMigrations(db) {
47
+ ensureMigrationsTable(db);
48
+ const applied = new Set(db.prepare('SELECT id FROM wa_migrations').all().map((r) => r.id));
49
+ const insertMigration = db.prepare('INSERT INTO wa_migrations (id, applied_at) VALUES (?, ?)');
50
+ for (const migration of MIGRATIONS) {
51
+ if (applied.has(migration.id))
52
+ continue;
53
+ const tx = db.transaction(() => {
54
+ db.exec(migration.sql);
55
+ insertMigration.run(migration.id, Date.now());
56
+ });
57
+ tx();
58
+ }
59
+ }
60
+ export async function useSqliteAuthState(opts) {
61
+ let db;
62
+ if (opts.database) {
63
+ db = opts.database;
64
+ }
65
+ else {
66
+ const Database = await loadBetterSqlite3();
67
+ db = new Database(opts.dbPath);
68
+ }
69
+ // WAL mode allows concurrent reads alongside a single writer; matches
70
+ // what SQLite recommends for read-heavy workloads with sporadic writes.
71
+ db.pragma('journal_mode = WAL');
72
+ db.pragma('synchronous = NORMAL');
73
+ runMigrations(db);
74
+ // Vanz@Fix (bug 8): periodic WAL checkpoint + cleanup old signal keys to prevent DB bloat.
75
+ // Runs every 30 minutes. WAL checkpoint reclaims WAL file space; key cleanup removes stale session entries.
76
+ const _walCleanupInterval = setInterval(() => {
77
+ try {
78
+ db.pragma('wal_checkpoint(PASSIVE)');
79
+ // Remove signal keys older than 30 days (pre-keys, session keys that have expired)
80
+ // Only removes types that are safe to prune (not creds or app-state-sync-key)
81
+ const pruneTypes = ['pre-key', 'session'];
82
+ for (const type of pruneTypes) {
83
+ try {
84
+ // Keep last 500 per type to avoid breaking active sessions
85
+ db.prepare(`
86
+ DELETE FROM signal_keys WHERE type = ? AND id NOT IN (
87
+ SELECT id FROM signal_keys WHERE type = ? ORDER BY rowid DESC LIMIT 500
88
+ )
89
+ `).run(type, type);
90
+ } catch { /* ignore per-type errors */ }
91
+ }
92
+ } catch { /* ignore checkpoint errors — non-fatal */ }
93
+ }, 30 * 60 * 1000);
94
+ // Allow Node process to exit even if interval is still running
95
+ if (_walCleanupInterval.unref) _walCleanupInterval.unref();
96
+ const stmts = {
97
+ credsSelect: db.prepare('SELECT value FROM creds WHERE key = ?'),
98
+ credsUpsert: db.prepare('INSERT INTO creds (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value'),
99
+ keySelect: db.prepare('SELECT value FROM signal_keys WHERE type = ? AND id = ?'),
100
+ keyUpsert: db.prepare('INSERT INTO signal_keys (type, id, value) VALUES (?, ?, ?) ON CONFLICT(type, id) DO UPDATE SET value = excluded.value'),
101
+ keyDelete: db.prepare('DELETE FROM signal_keys WHERE type = ? AND id = ?'),
102
+ keyListIds: db.prepare('SELECT id FROM signal_keys WHERE type = ?'),
103
+ keyList: db.prepare('SELECT id, value FROM signal_keys WHERE type = ?'),
104
+ clearKeys: db.prepare('DELETE FROM signal_keys')
105
+ };
106
+ const loadCreds = () => {
107
+ const row = stmts.credsSelect.get(CREDS_ROW_KEY);
108
+ if (!row)
109
+ return initAuthCreds();
110
+ return JSON.parse(row.value, BufferJSON.reviver);
111
+ };
112
+ const persistCreds = (creds) => {
113
+ stmts.credsUpsert.run(CREDS_ROW_KEY, JSON.stringify(creds, BufferJSON.replacer));
114
+ };
115
+ const creds = loadCreds();
116
+ return {
117
+ state: {
118
+ creds,
119
+ keys: {
120
+ get: async (type, ids) => {
121
+ const data = {};
122
+ for (const id of ids) {
123
+ const row = stmts.keySelect.get(type, id);
124
+ if (row) {
125
+ let value = JSON.parse(row.value, BufferJSON.reviver);
126
+ if (type === 'app-state-sync-key' && value) {
127
+ value = proto.Message.AppStateSyncKeyData.fromObject(value);
128
+ }
129
+ data[id] = value;
130
+ }
131
+ }
132
+ return data;
133
+ },
134
+ set: async (data) => {
135
+ const writeTx = db.transaction(() => {
136
+ for (const category in data) {
137
+ for (const id in data[category]) {
138
+ const value = data[category][id];
139
+ if (value) {
140
+ const stringified = JSON.stringify(value, BufferJSON.replacer);
141
+ stmts.keyUpsert.run(category, id, stringified);
142
+ }
143
+ else {
144
+ stmts.keyDelete.run(category, id);
145
+ }
146
+ }
147
+ }
148
+ });
149
+ writeTx();
150
+ }
151
+ }
152
+ },
153
+ saveCreds: async () => {
154
+ persistCreds(creds);
155
+ },
156
+ // Vanz@Fix: release the WAL cleanup interval and (if we opened it ourselves)
157
+ // the underlying db handle. Without this, every useSqliteAuthState() call
158
+ // (e.g. re-pairing / rotating sessions) leaked a timer + open sqlite fd forever.
159
+ close: async () => {
160
+ clearInterval(_walCleanupInterval);
161
+ if (!opts.database) {
162
+ try {
163
+ db.close();
164
+ }
165
+ catch { /* already closed */ }
166
+ }
167
+ }
168
+ };
169
+ }
170
+ //# sourceMappingURL=use-sqlite-auth-state.js.map
@@ -0,0 +1,42 @@
1
+ export function generateLoginNode(userJid: any, config: any): any;
2
+ export function generateRegistrationNode({ registrationId, signedPreKey, signedIdentityKey }: {
3
+ registrationId: any;
4
+ signedPreKey: any;
5
+ signedIdentityKey: any;
6
+ }, config: any): any;
7
+ export function configureSuccessfulPairing(stanza: any, { advSecretKey, signedIdentityKey, signalIdentities }: {
8
+ advSecretKey: any;
9
+ signedIdentityKey: any;
10
+ signalIdentities: any;
11
+ }): {
12
+ creds: {
13
+ account: any;
14
+ me: {
15
+ id: any;
16
+ name: any;
17
+ lid: any;
18
+ };
19
+ signalIdentities: any[];
20
+ platform: any;
21
+ };
22
+ reply: {
23
+ tag: string;
24
+ attrs: {
25
+ to: string;
26
+ type: string;
27
+ id: any;
28
+ };
29
+ content: {
30
+ tag: string;
31
+ attrs: {};
32
+ content: {
33
+ tag: string;
34
+ attrs: {
35
+ 'key-index': any;
36
+ };
37
+ content: any;
38
+ }[];
39
+ }[];
40
+ };
41
+ };
42
+ export function encodeSignedDeviceIdentity(account: any, includeSignatureKey: any): any;
@@ -0,0 +1,199 @@
1
+ import { Boom } from '@hapi/boom';
2
+ import { createHash } from 'crypto';
3
+ import { proto } from '../../WAProto/index.js';
4
+ import { KEY_BUNDLE_TYPE, WA_ADV_ACCOUNT_SIG_PREFIX, WA_ADV_DEVICE_SIG_PREFIX, WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX, COMPANION_DEVICE_VERSION } from '../Defaults/index.js';
5
+ import { getBinaryNodeChild, jidDecode, S_WHATSAPP_NET } from '../WABinary/index.js';
6
+ import { Curve, hmacSign } from './crypto.js';
7
+ import { encodeBigEndian } from './generics.js';
8
+ import { createSignalIdentity } from './signal.js';
9
+ const getUserAgent = (config) => {
10
+ return {
11
+ appVersion: {
12
+ primary: config.version[0],
13
+ secondary: config.version[1],
14
+ tertiary: config.version[2]
15
+ },
16
+ platform: proto.ClientPayload.UserAgent.Platform.WEB,
17
+ releaseChannel: proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
18
+ osVersion: '0.1',
19
+ device: 'Desktop',
20
+ osBuildNumber: '0.1',
21
+ localeLanguageIso6391: 'en',
22
+ mnc: '000',
23
+ mcc: '000',
24
+ localeCountryIso31661Alpha2: config.countryCode
25
+ };
26
+ };
27
+ const PLATFORM_MAP = {
28
+ 'Mac OS': proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
29
+ Windows: proto.ClientPayload.WebInfo.WebSubPlatform.WIN32
30
+ };
31
+ const getWebInfo = (config) => {
32
+ let webSubPlatform = proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER;
33
+ if (config.syncFullHistory &&
34
+ PLATFORM_MAP[config.browser[0]] &&
35
+ config.browser[1] === 'Desktop') {
36
+ webSubPlatform = PLATFORM_MAP[config.browser[0]];
37
+ }
38
+ return { webSubPlatform };
39
+ };
40
+ const getClientPayload = (config) => {
41
+ const payload = {
42
+ connectType: proto.ClientPayload.ConnectType.WIFI_UNKNOWN,
43
+ connectReason: proto.ClientPayload.ConnectReason.USER_ACTIVATED,
44
+ userAgent: getUserAgent(config)
45
+ };
46
+ payload.webInfo = getWebInfo(config);
47
+ if (config.pushName) {
48
+ payload.pushName = config.pushName;
49
+ }
50
+ return payload;
51
+ };
52
+ export const generateLoginNode = (userJid, config) => {
53
+ const { user, device } = jidDecode(userJid);
54
+ const payload = {
55
+ ...getClientPayload(config),
56
+ passive: true,
57
+ pull: true,
58
+ username: +user,
59
+ device: device,
60
+ // Vanz@Fix (bug 49): was hardcoded false — now reads from config.lidDbMigrated (default false until investigated)
61
+ lidDbMigrated: config.lidDbMigrated ?? false
62
+ };
63
+ return proto.ClientPayload.fromObject(payload);
64
+ };
65
+ const getPlatformType = (platform) => {
66
+ const platformType = platform.toUpperCase();
67
+ return (proto.DeviceProps.PlatformType[platformType] ||
68
+ proto.DeviceProps.PlatformType.CHROME);
69
+ };
70
+ export const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentityKey }, config) => {
71
+ // the app version needs to be md5 hashed
72
+ // and passed in
73
+ const appVersionBuf = createHash('md5')
74
+ .update(config.version.join('.')) // join as string
75
+ .digest();
76
+ const companion = {
77
+ os: config.browser[0],
78
+ platformType: getPlatformType(config.browser[1]),
79
+ requireFullSync: config.syncFullHistory,
80
+ historySyncConfig: {
81
+ storageQuotaMb: 10240,
82
+ inlineInitialPayloadInE2EeMsg: true,
83
+ recentSyncDaysLimit: undefined,
84
+ supportCallLogHistory: false,
85
+ supportBotUserAgentChatHistory: true,
86
+ supportCagReactionsAndPolls: true,
87
+ supportBizHostedMsg: true,
88
+ supportRecentSyncChunkMessageCountTuning: true,
89
+ supportHostedGroupMsg: true,
90
+ supportFbidBotChatHistory: true,
91
+ supportAddOnHistorySyncMigration: undefined,
92
+ supportMessageAssociation: true,
93
+ supportGroupHistory: false,
94
+ onDemandReady: undefined,
95
+ supportGuestChat: undefined
96
+ },
97
+ version: COMPANION_DEVICE_VERSION
98
+ };
99
+ const companionProto = proto.DeviceProps.encode(companion).finish();
100
+ const registerPayload = {
101
+ ...getClientPayload(config),
102
+ passive: false,
103
+ pull: false,
104
+ devicePairingData: {
105
+ buildHash: appVersionBuf,
106
+ deviceProps: companionProto,
107
+ eRegid: encodeBigEndian(registrationId),
108
+ eKeytype: KEY_BUNDLE_TYPE,
109
+ eIdent: signedIdentityKey.public,
110
+ eSkeyId: encodeBigEndian(signedPreKey.keyId, 3),
111
+ eSkeyVal: signedPreKey.keyPair.public,
112
+ eSkeySig: signedPreKey.signature
113
+ }
114
+ };
115
+ return proto.ClientPayload.fromObject(registerPayload);
116
+ };
117
+ export const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, signalIdentities }) => {
118
+ const msgId = stanza.attrs.id;
119
+ const pairSuccessNode = getBinaryNodeChild(stanza, 'pair-success');
120
+ const deviceIdentityNode = getBinaryNodeChild(pairSuccessNode, 'device-identity');
121
+ const platformNode = getBinaryNodeChild(pairSuccessNode, 'platform');
122
+ const deviceNode = getBinaryNodeChild(pairSuccessNode, 'device');
123
+ const businessNode = getBinaryNodeChild(pairSuccessNode, 'biz');
124
+ if (!deviceIdentityNode || !deviceNode) {
125
+ throw new Boom('Missing device-identity or device in pair success node', { data: stanza });
126
+ }
127
+ const bizName = businessNode?.attrs.name;
128
+ const jid = deviceNode.attrs.jid;
129
+ const lid = deviceNode.attrs.lid;
130
+ const { details, hmac, accountType } = proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content);
131
+ let hmacPrefix = Buffer.from([]);
132
+ if (accountType !== undefined && accountType === proto.ADVEncryptionType.HOSTED) {
133
+ hmacPrefix = WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX;
134
+ }
135
+ const advSign = hmacSign(Buffer.concat([hmacPrefix, details]), Buffer.from(advSecretKey, 'base64'));
136
+ if (Buffer.compare(hmac, advSign) !== 0) {
137
+ throw new Boom('Invalid account signature');
138
+ }
139
+ const account = proto.ADVSignedDeviceIdentity.decode(details);
140
+ const { accountSignatureKey, accountSignature, details: deviceDetails } = account;
141
+ const deviceIdentity = proto.ADVDeviceIdentity.decode(deviceDetails);
142
+ const accountSignaturePrefix = deviceIdentity.deviceType === proto.ADVEncryptionType.HOSTED
143
+ ? WA_ADV_HOSTED_ACCOUNT_SIG_PREFIX
144
+ : WA_ADV_ACCOUNT_SIG_PREFIX;
145
+ const accountMsg = Buffer.concat([accountSignaturePrefix, deviceDetails, signedIdentityKey.public]);
146
+ if (!Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
147
+ throw new Boom('Failed to verify account signature');
148
+ }
149
+ const deviceMsg = Buffer.concat([
150
+ WA_ADV_DEVICE_SIG_PREFIX,
151
+ deviceDetails,
152
+ signedIdentityKey.public,
153
+ accountSignatureKey
154
+ ]);
155
+ account.deviceSignature = Curve.sign(signedIdentityKey.private, deviceMsg);
156
+ const identity = createSignalIdentity(lid, accountSignatureKey);
157
+ const accountEnc = encodeSignedDeviceIdentity(account, false);
158
+ const reply = {
159
+ tag: 'iq',
160
+ attrs: {
161
+ to: S_WHATSAPP_NET,
162
+ type: 'result',
163
+ id: msgId
164
+ },
165
+ content: [
166
+ {
167
+ tag: 'pair-device-sign',
168
+ attrs: {},
169
+ content: [
170
+ {
171
+ tag: 'device-identity',
172
+ attrs: { 'key-index': deviceIdentity.keyIndex.toString() },
173
+ content: accountEnc
174
+ }
175
+ ]
176
+ }
177
+ ]
178
+ };
179
+ const authUpdate = {
180
+ account,
181
+ me: { id: jid, name: bizName, lid },
182
+ signalIdentities: [...(signalIdentities || []), identity],
183
+ platform: platformNode?.attrs.name
184
+ };
185
+ return {
186
+ creds: authUpdate,
187
+ reply
188
+ };
189
+ };
190
+ export const encodeSignedDeviceIdentity = (account, includeSignatureKey) => {
191
+ account = { ...account };
192
+ // set to null if we are not to include the signature key
193
+ // or if we are including the signature key but it is empty
194
+ if (!includeSignatureKey || !account.accountSignatureKey?.length) {
195
+ account.accountSignatureKey = null;
196
+ }
197
+ return proto.ADVSignedDeviceIdentity.encode(account).finish();
198
+ };
199
+ //# sourceMappingURL=validate-connection.js.map
@@ -0,0 +1,58 @@
1
+ export interface ContactPhone {
2
+ number: string;
3
+ type?: string;
4
+ label?: string;
5
+ }
6
+ export interface ContactEmail {
7
+ email: string;
8
+ type?: string;
9
+ }
10
+ export interface ContactUrl {
11
+ url: string;
12
+ type?: string;
13
+ }
14
+ export interface ContactAddress {
15
+ street?: string;
16
+ city?: string;
17
+ state?: string;
18
+ postalCode?: string;
19
+ country?: string;
20
+ type?: string;
21
+ }
22
+ export interface ContactData {
23
+ fullName: string;
24
+ displayName?: string;
25
+ organization?: string;
26
+ title?: string;
27
+ phones?: ContactPhone[];
28
+ emails?: ContactEmail[];
29
+ urls?: ContactUrl[];
30
+ addresses?: ContactAddress[];
31
+ birthday?: string;
32
+ note?: string;
33
+ }
34
+ export declare const escapeVCard: (s: string) => string;
35
+ export declare const formatPhone: (p: string) => string;
36
+ export declare const generateVCard: (c: ContactData) => string;
37
+ export declare const generateVCards: (contacts: ContactData[]) => string;
38
+ export declare const parseVCard: (vcard: string) => Partial<ContactData>;
39
+ export declare const createContactCard: (contact: ContactData) => {
40
+ contacts: {
41
+ displayName: string;
42
+ contacts: {
43
+ vcard: string;
44
+ }[];
45
+ };
46
+ };
47
+ export declare const createContactCards: (contacts: ContactData[]) => {
48
+ contacts: {
49
+ displayName: string;
50
+ contacts: {
51
+ vcard: string;
52
+ }[];
53
+ };
54
+ };
55
+ export declare const quickContact: (name: string, phone: string, options?: {
56
+ organization?: string;
57
+ email?: string;
58
+ }) => ContactData;
@@ -0,0 +1,105 @@
1
+ // Vanz@Add --- ported from Bail-master addons/vcard.ts (type-only
2
+ // annotations dropped; behavior unchanged).
3
+ export const escapeVCard = (s) => s.replace(/\\/g, '\\\\').replace(/;/g, '\\;').replace(/,/g, '\\,').replace(/\n/g, '\\n');
4
+ // Vanz@Fix 30-08-26 --- the old inline unescape used for FN/ORG/TITLE,
5
+ // `value.replace(/\\([;,n\\])/g, '$1')`, mishandled the `\n` case: it matched
6
+ // the backslash + literal "n" produced by escapeVCard's `\n` escape, then
7
+ // substituted back just the captured "n" character instead of a real newline
8
+ // (`$1` is literally the char "n", not the escape sequence). So a name/org/
9
+ // title containing a real newline round-tripped as "n" inserted in place of
10
+ // the line break instead of the original newline. NOTE already unescaped
11
+ // `\n` correctly on its own, separately. This single helper now reverses
12
+ // every escape escapeVCard() produces (backslash, semicolon, comma, newline)
13
+ // the same correct way, and is reused for all four fields below.
14
+ export const unescapeVCard = (s) => s.replace(/\\(.)/g, (_, ch) => (ch === 'n' ? '\n' : ch));
15
+ export const formatPhone = (p) => p.replace(/[^\d+]/g, '');
16
+ /** Build a VCARD 3.0 string from structured contact data. */
17
+ export const generateVCard = (c) => {
18
+ const lines = ['BEGIN:VCARD', 'VERSION:3.0', `FN:${escapeVCard(c.fullName)}`];
19
+ const parts = c.fullName.split(' ');
20
+ if (parts.length >= 2) {
21
+ const last = parts[parts.length - 1] || '';
22
+ const first = parts.slice(0, -1).join(' ');
23
+ lines.push(`N:${escapeVCard(last)};${escapeVCard(first)};;;`);
24
+ }
25
+ else {
26
+ lines.push(`N:${escapeVCard(c.fullName)};;;;`);
27
+ }
28
+ if (c.organization)
29
+ lines.push(`ORG:${escapeVCard(c.organization)}`);
30
+ if (c.title)
31
+ lines.push(`TITLE:${escapeVCard(c.title)}`);
32
+ for (const p of c.phones ?? []) {
33
+ const t = p.type || 'CELL';
34
+ const n = formatPhone(p.number);
35
+ lines.push(p.label ? `TEL;type=${t};type=VOICE;X-ABLabel=${escapeVCard(p.label)}:${n}` : `TEL;type=${t};type=VOICE:${n}`);
36
+ }
37
+ for (const e of c.emails ?? [])
38
+ lines.push(`EMAIL;type=${e.type || 'OTHER'}:${e.email}`);
39
+ for (const u of c.urls ?? [])
40
+ lines.push(`URL;type=${u.type || 'OTHER'}:${u.url}`);
41
+ for (const a of c.addresses ?? []) {
42
+ const t = a.type || 'OTHER';
43
+ const parts = ['', '', a.street || '', a.city || '', a.state || '', a.postalCode || '', a.country || ''].map((v) => escapeVCard(v));
44
+ lines.push(`ADR;type=${t}:${parts.join(';')}`);
45
+ }
46
+ if (c.birthday)
47
+ lines.push(`BDAY:${c.birthday}`);
48
+ if (c.note)
49
+ lines.push(`NOTE:${escapeVCard(c.note)}`);
50
+ lines.push('END:VCARD');
51
+ return lines.join('\r\n');
52
+ };
53
+ export const generateVCards = (contacts) => contacts.map(generateVCard).join('\r\n');
54
+ /** Parse a subset of VCARD fields back into structured data. */
55
+ export const parseVCard = (vcard) => {
56
+ const contact = {};
57
+ for (const line of vcard.split(/\r?\n/)) {
58
+ const [key, ...vp] = line.split(':');
59
+ if (!key)
60
+ continue;
61
+ const value = vp.join(':');
62
+ if (key.startsWith('FN'))
63
+ contact.fullName = unescapeVCard(value);
64
+ else if (key.startsWith('ORG'))
65
+ contact.organization = unescapeVCard(value);
66
+ else if (key.startsWith('TITLE'))
67
+ contact.title = unescapeVCard(value);
68
+ else if (key.startsWith('TEL')) {
69
+ contact.phones = contact.phones || [];
70
+ const tm = key.match(/type=(\w+)/i);
71
+ contact.phones.push({ number: value, type: tm?.[1]?.toUpperCase() || 'CELL' });
72
+ }
73
+ else if (key.startsWith('EMAIL')) {
74
+ contact.emails = contact.emails || [];
75
+ const tm = key.match(/type=(\w+)/i);
76
+ contact.emails.push({ email: value, type: tm?.[1]?.toUpperCase() || 'OTHER' });
77
+ }
78
+ else if (key.startsWith('BDAY'))
79
+ contact.birthday = value;
80
+ else if (key.startsWith('NOTE'))
81
+ contact.note = unescapeVCard(value);
82
+ }
83
+ return contact;
84
+ };
85
+ /** Ready-to-send `contacts` message content for a single contact. */
86
+ export const createContactCard = (contact) => ({
87
+ contacts: {
88
+ displayName: contact.displayName || contact.fullName,
89
+ contacts: [{ vcard: generateVCard(contact) }]
90
+ }
91
+ });
92
+ /** Ready-to-send `contacts` message content for multiple contacts. */
93
+ export const createContactCards = (contacts) => ({
94
+ contacts: {
95
+ displayName: contacts.length === 1 ? contacts[0]?.displayName || contacts[0]?.fullName || '' : `${contacts.length} Contacts`,
96
+ contacts: contacts.map((c) => ({ vcard: generateVCard(c) }))
97
+ }
98
+ });
99
+ export const quickContact = (name, phone, options) => ({
100
+ fullName: name,
101
+ phones: [{ number: phone, type: 'CELL' }],
102
+ organization: options?.organization,
103
+ emails: options?.email ? [{ email: options.email, type: 'WORK' }] : undefined
104
+ });
105
+ //# sourceMappingURL=vcard.js.map
@@ -0,0 +1,15 @@
1
+ export declare class AudioFeeder {
2
+ #private;
3
+ private readonly sampleRate;
4
+ private readonly channels;
5
+ private readonly framesPerChunk;
6
+ private readonly onChunk;
7
+ private readonly source;
8
+ droppedChunks: number;
9
+ underflowChunks: number;
10
+ bytesProduced: number;
11
+ chunksEmitted: number;
12
+ constructor(sampleRate: number, channels: number, framesPerChunk: number, onChunk: (chunk: Float32Array) => void, source?: string);
13
+ start: () => void;
14
+ stop: () => void;
15
+ }