@periskope/baileys 6.7.18-17-2 → 6.7.18-17-4

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.
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GroupCipher = void 0;
4
+ /* @ts-ignore */
4
5
  const crypto_1 = require("libsignal/src/crypto");
5
6
  const sender_key_message_1 = require("./sender-key-message");
6
7
  class GroupCipher {
@@ -30,13 +31,9 @@ class GroupCipher {
30
31
  throw new Error('No SenderKeyRecord found for decryption');
31
32
  }
32
33
  const senderKeyMessage = new sender_key_message_1.SenderKeyMessage(null, null, null, null, senderKeyMessageBytes);
33
- let senderKeyState = record.getSenderKeyState(senderKeyMessage.getKeyId());
34
- // Fallback: try to get the latest sender key state if specific keyId not found
34
+ const senderKeyState = record.getSenderKeyState(senderKeyMessage.getKeyId());
35
35
  if (!senderKeyState) {
36
- senderKeyState = record.getSenderKeyState();
37
- if (!senderKeyState) {
38
- throw new Error('No session found to decrypt message');
39
- }
36
+ throw new Error('No session found to decrypt message');
40
37
  }
41
38
  senderKeyMessage.verifySignature(senderKeyState.getSigningKeyPublic());
42
39
  const senderKey = this.getSenderKey(senderKeyState, senderKeyMessage.getIteration());
@@ -1,3 +1,3 @@
1
- import { SignalAuthState } from '../Types';
2
- import { SignalRepository } from '../Types/Signal';
1
+ import type { SignalAuthState } from '../Types';
2
+ import type { SignalRepository } from '../Types/Signal';
3
3
  export declare function makeLibSignalRepository(auth: SignalAuthState): SignalRepository;
@@ -35,19 +35,29 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.makeLibSignalRepository = makeLibSignalRepository;
37
37
  const libsignal = __importStar(require("libsignal"));
38
+ /* @ts-ignore */
39
+ const lru_cache_1 = require("lru-cache");
38
40
  const Utils_1 = require("../Utils");
39
41
  const WABinary_1 = require("../WABinary");
40
42
  const sender_key_name_1 = require("./Group/sender-key-name");
41
43
  const sender_key_record_1 = require("./Group/sender-key-record");
42
44
  const Group_1 = require("./Group");
45
+ const lid_mapping_1 = require("./lid-mapping");
43
46
  function makeLibSignalRepository(auth) {
44
- const storage = signalStorage(auth);
45
- return {
47
+ const lidMapping = new lid_mapping_1.LIDMappingStore(auth.keys);
48
+ const storage = signalStorage(auth, lidMapping);
49
+ // Simple operation-level deduplication (5 minutes)
50
+ const recentMigrations = new lru_cache_1.LRUCache({
51
+ max: 500,
52
+ ttl: 5 * 60 * 1000
53
+ });
54
+ const parsedKeys = auth.keys;
55
+ const repository = {
46
56
  decryptGroupMessage({ group, authorJid, msg }) {
47
57
  const senderName = jidToSignalSenderKeyName(group, authorJid);
48
58
  const cipher = new Group_1.GroupCipher(storage, senderName);
49
59
  // Use transaction to ensure atomicity
50
- return auth.keys.transaction(async () => {
60
+ return parsedKeys.transaction(async () => {
51
61
  return cipher.decrypt(msg);
52
62
  });
53
63
  },
@@ -59,7 +69,11 @@ function makeLibSignalRepository(auth) {
59
69
  const senderName = jidToSignalSenderKeyName(item.groupId, authorJid);
60
70
  const senderMsg = new Group_1.SenderKeyDistributionMessage(null, null, null, null, item.axolotlSenderKeyDistributionMessage);
61
71
  const senderNameStr = senderName.toString();
62
- return auth.keys.transaction(async () => {
72
+ const { [senderNameStr]: senderKey } = await auth.keys.get('sender-key', [senderNameStr]);
73
+ if (!senderKey) {
74
+ await storage.storeSenderKey(senderName, new sender_key_record_1.SenderKeyRecord());
75
+ }
76
+ return parsedKeys.transaction(async () => {
63
77
  const { [senderNameStr]: senderKey } = await auth.keys.get('sender-key', [senderNameStr]);
64
78
  if (!senderKey) {
65
79
  await storage.storeSenderKey(senderName, new sender_key_record_1.SenderKeyRecord());
@@ -70,8 +84,8 @@ function makeLibSignalRepository(auth) {
70
84
  async decryptMessage({ jid, type, ciphertext }) {
71
85
  const addr = jidToSignalProtocolAddress(jid);
72
86
  const session = new libsignal.SessionCipher(storage, addr);
73
- // Use transaction to ensure atomicityAdd commentMore actions
74
- return auth.keys.transaction(async () => {
87
+ // Use transaction to ensure atomicity
88
+ return parsedKeys.transaction(async () => {
75
89
  let result;
76
90
  switch (type) {
77
91
  case 'pkmsg':
@@ -80,15 +94,41 @@ function makeLibSignalRepository(auth) {
80
94
  case 'msg':
81
95
  result = await session.decryptWhisperMessage(ciphertext);
82
96
  break;
97
+ default:
98
+ throw new Error(`Unknown message type: ${type}`);
83
99
  }
84
100
  return result;
85
101
  });
86
102
  },
87
103
  async encryptMessage({ jid, data }) {
88
- const addr = jidToSignalProtocolAddress(jid);
104
+ // LID SINGLE SOURCE OF TRUTH: Always prefer LID when available
105
+ let encryptionJid = jid;
106
+ // Check for LID mapping and use it if session exists
107
+ if (jid.includes('@s.whatsapp.net')) {
108
+ const lidForPN = await lidMapping.getLIDForPN(jid);
109
+ if (lidForPN === null || lidForPN === void 0 ? void 0 : lidForPN.includes('@lid')) {
110
+ const lidAddr = jidToSignalProtocolAddress(lidForPN);
111
+ const { [lidAddr.toString()]: lidSession } = await auth.keys.get('session', [lidAddr.toString()]);
112
+ if (lidSession) {
113
+ // LID session exists, use it
114
+ encryptionJid = lidForPN;
115
+ }
116
+ else {
117
+ // Try to migrate if PN session exists
118
+ const pnAddr = jidToSignalProtocolAddress(jid);
119
+ const { [pnAddr.toString()]: pnSession } = await auth.keys.get('session', [pnAddr.toString()]);
120
+ if (pnSession) {
121
+ // Migrate PN to LID
122
+ await repository.migrateSession(jid, lidForPN);
123
+ encryptionJid = lidForPN;
124
+ }
125
+ }
126
+ }
127
+ }
128
+ const addr = jidToSignalProtocolAddress(encryptionJid);
89
129
  const cipher = new libsignal.SessionCipher(storage, addr);
90
- // Use transaction to ensure atomicityAdd commentMore actions
91
- return auth.keys.transaction(async () => {
130
+ // Use transaction to ensure atomicity
131
+ return parsedKeys.transaction(async () => {
92
132
  const { type: sigType, body } = await cipher.encrypt(data);
93
133
  const type = sigType === 3 ? 'pkmsg' : 'msg';
94
134
  return { type, ciphertext: Buffer.from(body, 'binary') };
@@ -98,8 +138,7 @@ function makeLibSignalRepository(auth) {
98
138
  const senderName = jidToSignalSenderKeyName(group, meId);
99
139
  const builder = new Group_1.GroupSessionBuilder(storage);
100
140
  const senderNameStr = senderName.toString();
101
- // Use transaction to ensure atomicity
102
- return auth.keys.transaction(async () => {
141
+ return parsedKeys.transaction(async () => {
103
142
  const { [senderNameStr]: senderKey } = await auth.keys.get('sender-key', [senderNameStr]);
104
143
  if (!senderKey) {
105
144
  await storage.storeSenderKey(senderName, new sender_key_record_1.SenderKeyRecord());
@@ -115,31 +154,136 @@ function makeLibSignalRepository(auth) {
115
154
  },
116
155
  async injectE2ESession({ jid, session }) {
117
156
  const cipher = new libsignal.SessionBuilder(storage, jidToSignalProtocolAddress(jid));
118
- // Use transaction to ensure atomicity
119
- return auth.keys.transaction(async () => {
157
+ return parsedKeys.transaction(async () => {
120
158
  await cipher.initOutgoing(session);
121
159
  });
122
160
  },
123
161
  jidToSignalProtocolAddress(jid) {
124
162
  return jidToSignalProtocolAddress(jid).toString();
163
+ },
164
+ async storeLIDPNMapping(lid, pn) {
165
+ await lidMapping.storeLIDPNMapping(lid, pn);
166
+ },
167
+ getLIDMappingStore() {
168
+ return lidMapping;
169
+ },
170
+ async validateSession(jid) {
171
+ try {
172
+ const addr = jidToSignalProtocolAddress(jid);
173
+ const session = await storage.loadSession(addr.toString());
174
+ if (!session) {
175
+ return { exists: false, reason: 'no session' };
176
+ }
177
+ if (!session.haveOpenSession()) {
178
+ return { exists: false, reason: 'no open session' };
179
+ }
180
+ return { exists: true };
181
+ }
182
+ catch (error) {
183
+ return { exists: false, reason: 'validation error' };
184
+ }
185
+ },
186
+ async deleteSession(jid) {
187
+ const addr = jidToSignalProtocolAddress(jid);
188
+ return auth.keys.transaction(async () => {
189
+ await auth.keys.set({ session: { [addr.toString()]: null } });
190
+ });
191
+ },
192
+ async migrateSession(fromJid, toJid) {
193
+ // Only migrate PN → LID
194
+ if (!fromJid.includes('@s.whatsapp.net') || !toJid.includes('@lid')) {
195
+ return;
196
+ }
197
+ const fromDecoded = (0, WABinary_1.jidDecode)(fromJid);
198
+ const toDecoded = (0, WABinary_1.jidDecode)(toJid);
199
+ if (!fromDecoded || !toDecoded)
200
+ return;
201
+ const deviceId = fromDecoded.device || 0;
202
+ const migrationKey = `${fromDecoded.user}.${deviceId}→${toDecoded.user}.${deviceId}`;
203
+ // Check if recently migrated (5 min window)
204
+ if (recentMigrations.has(migrationKey)) {
205
+ return;
206
+ }
207
+ // Check if LID session already exists
208
+ const lidAddr = jidToSignalProtocolAddress(toJid);
209
+ const { [lidAddr.toString()]: lidExists } = await auth.keys.get('session', [lidAddr.toString()]);
210
+ if (lidExists) {
211
+ recentMigrations.set(migrationKey, true);
212
+ return;
213
+ }
214
+ return auth.keys.transaction(async () => {
215
+ // Store mapping
216
+ await lidMapping.storeLIDPNMapping(toJid, fromJid);
217
+ // Load and copy session
218
+ const fromAddr = jidToSignalProtocolAddress(fromJid);
219
+ const fromSession = await storage.loadSession(fromAddr.toString());
220
+ if (fromSession === null || fromSession === void 0 ? void 0 : fromSession.haveOpenSession()) {
221
+ // Deep copy session to prevent reference issues
222
+ const sessionBytes = fromSession.serialize();
223
+ const copiedSession = libsignal.SessionRecord.deserialize(sessionBytes);
224
+ // Store at LID address
225
+ await storage.storeSession(lidAddr.toString(), copiedSession);
226
+ // Delete PN session - maintain single encryption layer
227
+ await auth.keys.set({ session: { [fromAddr.toString()]: null } });
228
+ }
229
+ recentMigrations.set(migrationKey, true);
230
+ });
231
+ },
232
+ async encryptMessageWithWire({ encryptionJid, wireJid, data }) {
233
+ const result = await repository.encryptMessage({ jid: encryptionJid, data });
234
+ return { ...result, wireJid };
235
+ },
236
+ destroy() {
237
+ recentMigrations.clear();
125
238
  }
126
239
  };
240
+ return repository;
127
241
  }
128
242
  const jidToSignalProtocolAddress = (jid) => {
129
- const { user, device } = (0, WABinary_1.jidDecode)(jid);
130
- return new libsignal.ProtocolAddress(user, device || 0);
243
+ const decoded = (0, WABinary_1.jidDecode)(jid);
244
+ const { user, device, server } = decoded;
245
+ // LID addresses get _1 suffix for Signal protocol
246
+ const signalUser = server === 'lid' ? `${user}_1` : user;
247
+ const finalDevice = device || 0;
248
+ return new libsignal.ProtocolAddress(signalUser, finalDevice);
131
249
  };
132
250
  const jidToSignalSenderKeyName = (group, user) => {
133
251
  return new sender_key_name_1.SenderKeyName(group, jidToSignalProtocolAddress(user));
134
252
  };
135
- function signalStorage({ creds, keys }) {
253
+ function signalStorage({ creds, keys }, lidMapping) {
136
254
  return {
137
255
  loadSession: async (id) => {
138
- const { [id]: sess } = await keys.get('session', [id]);
139
- if (sess) {
140
- return libsignal.SessionRecord.deserialize(sess);
256
+ try {
257
+ // LID SINGLE SOURCE OF TRUTH: Auto-redirect PN to LID if mapping exists
258
+ let actualId = id;
259
+ if (id.includes('.') && !id.includes('_1')) {
260
+ // This is a PN signal address format (e.g., "1234567890.0")
261
+ // Convert back to JID to check for LID mapping
262
+ const parts = id.split('.');
263
+ const device = parts[1] || '0';
264
+ const pnJid = device === '0' ? `${parts[0]}@s.whatsapp.net` : `${parts[0]}:${device}@s.whatsapp.net`;
265
+ const lidForPN = await lidMapping.getLIDForPN(pnJid);
266
+ if (lidForPN === null || lidForPN === void 0 ? void 0 : lidForPN.includes('@lid')) {
267
+ const lidAddr = jidToSignalProtocolAddress(lidForPN);
268
+ const lidId = lidAddr.toString();
269
+ // Check if LID session exists
270
+ const { [lidId]: lidSession } = await keys.get('session', [lidId]);
271
+ if (lidSession) {
272
+ actualId = lidId;
273
+ }
274
+ }
275
+ }
276
+ const { [actualId]: sess } = await keys.get('session', [actualId]);
277
+ if (sess) {
278
+ return libsignal.SessionRecord.deserialize(sess);
279
+ }
280
+ }
281
+ catch (e) {
282
+ return null;
141
283
  }
284
+ return null;
142
285
  },
286
+ // TODO: Replace with libsignal.SessionRecord when type exports are added to libsignal
143
287
  storeSession: async (id, session) => {
144
288
  await keys.set({ session: { [id]: session.serialize() } });
145
289
  },
@@ -0,0 +1,17 @@
1
+ import type { SignalKeyStoreWithTransaction } from '../Types';
2
+ export declare class LIDMappingStore {
3
+ private readonly keys;
4
+ constructor(keys: SignalKeyStoreWithTransaction);
5
+ /**
6
+ * Store LID-PN mapping - USER LEVEL
7
+ */
8
+ storeLIDPNMapping(lid: string, pn: string): Promise<void>;
9
+ /**
10
+ * Get LID for PN - Returns device-specific LID based on user mapping
11
+ */
12
+ getLIDForPN(pn: string): Promise<string | null>;
13
+ /**
14
+ * Get PN for LID - USER LEVEL with device construction
15
+ */
16
+ getPNForLID(lid: string): Promise<string | null>;
17
+ }
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LIDMappingStore = void 0;
7
+ const logger_1 = __importDefault(require("../Utils/logger"));
8
+ const WABinary_1 = require("../WABinary");
9
+ class LIDMappingStore {
10
+ constructor(keys) {
11
+ this.keys = keys;
12
+ }
13
+ /**
14
+ * Store LID-PN mapping - USER LEVEL
15
+ */
16
+ async storeLIDPNMapping(lid, pn) {
17
+ // Validate inputs
18
+ if (!(((0, WABinary_1.isLidUser)(lid) && (0, WABinary_1.isJidUser)(pn)) || ((0, WABinary_1.isJidUser)(lid) && (0, WABinary_1.isLidUser)(pn)))) {
19
+ logger_1.default.warn(`Invalid LID-PN mapping: ${lid}, ${pn}`);
20
+ return;
21
+ }
22
+ const [lidJid, pnJid] = (0, WABinary_1.isLidUser)(lid) ? [lid, pn] : [pn, lid];
23
+ const lidDecoded = (0, WABinary_1.jidDecode)(lidJid);
24
+ const pnDecoded = (0, WABinary_1.jidDecode)(pnJid);
25
+ if (!lidDecoded || !pnDecoded)
26
+ return;
27
+ const pnUser = pnDecoded.user;
28
+ const lidUser = lidDecoded.user;
29
+ logger_1.default.trace(`Storing USER LID mapping: PN ${pnUser} → LID ${lidUser}`);
30
+ await this.keys.transaction(async () => {
31
+ await this.keys.set({
32
+ 'lid-mapping': {
33
+ [pnUser]: lidUser, // "554396160286" -> "102765716062358"
34
+ [`${lidUser}_reverse`]: pnUser // "102765716062358_reverse" -> "554396160286"
35
+ }
36
+ });
37
+ });
38
+ logger_1.default.trace(`USER LID mapping stored: PN ${pnUser} → LID ${lidUser}`);
39
+ }
40
+ /**
41
+ * Get LID for PN - Returns device-specific LID based on user mapping
42
+ */
43
+ async getLIDForPN(pn) {
44
+ if (!(0, WABinary_1.isJidUser)(pn))
45
+ return null;
46
+ const decoded = (0, WABinary_1.jidDecode)(pn);
47
+ if (!decoded)
48
+ return null;
49
+ // Look up user-level mapping (whatsmeow approach)
50
+ const pnUser = decoded.user;
51
+ const stored = await this.keys.get('lid-mapping', [pnUser]);
52
+ const lidUser = stored[pnUser];
53
+ if (!lidUser) {
54
+ logger_1.default.trace(`No LID mapping found for PN user ${pnUser}`);
55
+ return null;
56
+ }
57
+ if (typeof lidUser !== 'string')
58
+ return null;
59
+ // Push the PN device ID to the LID to maintain device separation
60
+ const pnDevice = decoded.device !== undefined ? decoded.device : 0;
61
+ const deviceSpecificLid = `${lidUser}:${pnDevice}@lid`;
62
+ logger_1.default.trace(`getLIDForPN: ${pn} → ${deviceSpecificLid} (user mapping with device ${pnDevice})`);
63
+ return deviceSpecificLid;
64
+ }
65
+ /**
66
+ * Get PN for LID - USER LEVEL with device construction
67
+ */
68
+ async getPNForLID(lid) {
69
+ if (!(0, WABinary_1.isLidUser)(lid))
70
+ return null;
71
+ const decoded = (0, WABinary_1.jidDecode)(lid);
72
+ if (!decoded)
73
+ return null;
74
+ // Look up reverse user mapping
75
+ const lidUser = decoded.user;
76
+ const stored = await this.keys.get('lid-mapping', [`${lidUser}_reverse`]);
77
+ const pnUser = stored[`${lidUser}_reverse`];
78
+ if (!pnUser || typeof pnUser !== 'string') {
79
+ logger_1.default.trace(`No reverse mapping found for LID user: ${lidUser}`);
80
+ return null;
81
+ }
82
+ // Construct device-specific PN JID
83
+ const lidDevice = decoded.device !== undefined ? decoded.device : 0;
84
+ const pnJid = `${pnUser}:${lidDevice}@s.whatsapp.net`;
85
+ logger_1.default.trace(`Found reverse mapping: ${lid} → ${pnJid}`);
86
+ return pnJid;
87
+ }
88
+ }
89
+ exports.LIDMappingStore = LIDMappingStore;
@@ -32,11 +32,13 @@ export declare const makeBusinessSocket: (config: SocketConfig) => {
32
32
  [_: string]: string;
33
33
  }>;
34
34
  sendPeerDataOperationMessage: (pdoMessage: import("../Types").WAProto.Message.IPeerDataOperationRequestMessage) => Promise<string>;
35
- createParticipantNodes: (jids: string[], message: import("../Types").WAProto.IMessage, extraAttrs?: BinaryNode["attrs"]) => Promise<{
35
+ createParticipantNodes: (jids: string[], message: import("../Types").WAProto.IMessage, extraAttrs?: BinaryNode["attrs"], dsmMessage?: import("../Types").WAProto.IMessage) => Promise<{
36
36
  nodes: BinaryNode[];
37
37
  shouldIncludeDeviceIdentity: boolean;
38
38
  }>;
39
- getUSyncDevices: (jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => Promise<import("../WABinary").JidWithDevice[]>;
39
+ getUSyncDevices: (jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => Promise<(import("../WABinary").JidWithDevice & {
40
+ wireJid: string;
41
+ })[]>;
40
42
  updateMediaMessage: (message: import("../Types").WAProto.IWebMessageInfo) => Promise<import("../Types").WAProto.IWebMessageInfo>;
41
43
  sendMessage: (jid: string, content: import("../Types").AnyMessageContent, options?: import("../Types").MiscMessageGenerationOptions) => Promise<import("../Types").WAProto.WebMessageInfo | undefined>;
42
44
  newsletterCreate: (name: string, description?: string) => Promise<import("../Types").NewsletterMetadata>;
@@ -31,11 +31,13 @@ declare const makeWASocket: (config: UserFacingSocketConfig) => {
31
31
  [_: string]: string;
32
32
  }>;
33
33
  sendPeerDataOperationMessage: (pdoMessage: import("../Types").WAProto.Message.IPeerDataOperationRequestMessage) => Promise<string>;
34
- createParticipantNodes: (jids: string[], message: import("../Types").WAProto.IMessage, extraAttrs?: import("..").BinaryNode["attrs"]) => Promise<{
34
+ createParticipantNodes: (jids: string[], message: import("../Types").WAProto.IMessage, extraAttrs?: import("..").BinaryNode["attrs"], dsmMessage?: import("../Types").WAProto.IMessage) => Promise<{
35
35
  nodes: import("..").BinaryNode[];
36
36
  shouldIncludeDeviceIdentity: boolean;
37
37
  }>;
38
- getUSyncDevices: (jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => Promise<import("..").JidWithDevice[]>;
38
+ getUSyncDevices: (jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => Promise<(import("..").JidWithDevice & {
39
+ wireJid: string;
40
+ })[]>;
39
41
  updateMediaMessage: (message: import("../Types").WAProto.IWebMessageInfo) => Promise<import("../Types").WAProto.IWebMessageInfo>;
40
42
  sendMessage: (jid: string, content: import("../Types").AnyMessageContent, options?: import("../Types").MiscMessageGenerationOptions) => Promise<import("../Types").WAProto.WebMessageInfo | undefined>;
41
43
  newsletterCreate: (name: string, description?: string) => Promise<import("../Types").NewsletterMetadata>;
@@ -21,11 +21,13 @@ export declare const makeMessagesRecvSocket: (config: SocketConfig) => {
21
21
  [_: string]: string;
22
22
  }>;
23
23
  sendPeerDataOperationMessage: (pdoMessage: proto.Message.IPeerDataOperationRequestMessage) => Promise<string>;
24
- createParticipantNodes: (jids: string[], message: proto.IMessage, extraAttrs?: BinaryNode["attrs"]) => Promise<{
24
+ createParticipantNodes: (jids: string[], message: proto.IMessage, extraAttrs?: BinaryNode["attrs"], dsmMessage?: proto.IMessage) => Promise<{
25
25
  nodes: BinaryNode[];
26
26
  shouldIncludeDeviceIdentity: boolean;
27
27
  }>;
28
- getUSyncDevices: (jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => Promise<import("../WABinary").JidWithDevice[]>;
28
+ getUSyncDevices: (jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => Promise<(import("../WABinary").JidWithDevice & {
29
+ wireJid: string;
30
+ })[]>;
29
31
  updateMediaMessage: (message: proto.IWebMessageInfo) => Promise<proto.IWebMessageInfo>;
30
32
  sendMessage: (jid: string, content: import("../Types").AnyMessageContent, options?: import("../Types").MiscMessageGenerationOptions) => Promise<proto.WebMessageInfo | undefined>;
31
33
  newsletterCreate: (name: string, description?: string) => Promise<import("../Types").NewsletterMetadata>;
@@ -661,7 +661,7 @@ const makeMessagesRecvSocket = (config) => {
661
661
  }
662
662
  };
663
663
  const handleMessage = async (node) => {
664
- var _a, _b, _c;
664
+ var _a, _b, _c, _d, _e, _f, _g;
665
665
  if (shouldIgnoreJid(node.attrs.from) && node.attrs.from !== '@s.whatsapp.net') {
666
666
  logger.debug({ key: node.attrs.key }, 'ignored message');
667
667
  await sendMessageAck(node);
@@ -697,6 +697,36 @@ const makeMessagesRecvSocket = (config) => {
697
697
  node.attrs.sender_pn) {
698
698
  ev.emit('chats.phoneNumberShare', { lid: node.attrs.from, jid: node.attrs.sender_pn });
699
699
  }
700
+ if ((_f = (_e = (_d = msg.message) === null || _d === void 0 ? void 0 : _d.protocolMessage) === null || _e === void 0 ? void 0 : _e.lidMigrationMappingSyncMessage) === null || _f === void 0 ? void 0 : _f.encodedMappingPayload) {
701
+ try {
702
+ const payload = msg.message.protocolMessage.lidMigrationMappingSyncMessage.encodedMappingPayload;
703
+ const decoded = WAProto_1.proto.LIDMigrationMappingSyncPayload.decode(payload);
704
+ logger.debug({
705
+ mappingCount: ((_g = decoded.pnToLidMappings) === null || _g === void 0 ? void 0 : _g.length) || 0,
706
+ timestamp: decoded.chatDbMigrationTimestamp
707
+ }, 'Received LID migration sync message from server');
708
+ const lidMapping = signalRepository.getLIDMappingStore();
709
+ if (decoded.pnToLidMappings && decoded.pnToLidMappings.length > 0) {
710
+ for (const mapping of decoded.pnToLidMappings) {
711
+ const pn = `${mapping.pn}@s.whatsapp.net`;
712
+ // Use latestLid if available, otherwise assignedLid (proper LID refresh)
713
+ const lidValue = mapping.latestLid || mapping.assignedLid;
714
+ const lid = `${lidValue}@lid`;
715
+ await lidMapping.storeLIDPNMapping(lid, pn);
716
+ logger.debug({
717
+ pn,
718
+ lid,
719
+ assignedLid: mapping.assignedLid,
720
+ latestLid: mapping.latestLid,
721
+ usedLatest: !!mapping.latestLid
722
+ }, 'Stored server-provided PN-LID mapping');
723
+ }
724
+ }
725
+ }
726
+ catch (error) {
727
+ logger.error({ error }, 'Failed to process LID migration sync message');
728
+ }
729
+ }
700
730
  try {
701
731
  await Promise.all([
702
732
  processingMutex.mutex(async () => {
@@ -16,11 +16,13 @@ export declare const makeMessagesSocket: (config: SocketConfig) => {
16
16
  [_: string]: string;
17
17
  }>;
18
18
  sendPeerDataOperationMessage: (pdoMessage: proto.Message.IPeerDataOperationRequestMessage) => Promise<string>;
19
- createParticipantNodes: (jids: string[], message: proto.IMessage, extraAttrs?: BinaryNode["attrs"]) => Promise<{
19
+ createParticipantNodes: (jids: string[], message: proto.IMessage, extraAttrs?: BinaryNode["attrs"], dsmMessage?: proto.IMessage) => Promise<{
20
20
  nodes: BinaryNode[];
21
21
  shouldIncludeDeviceIdentity: boolean;
22
22
  }>;
23
- getUSyncDevices: (jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => Promise<JidWithDevice[]>;
23
+ getUSyncDevices: (jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => Promise<(JidWithDevice & {
24
+ wireJid: string;
25
+ })[]>;
24
26
  updateMediaMessage: (message: proto.IWebMessageInfo) => Promise<proto.IWebMessageInfo>;
25
27
  sendMessage: (jid: string, content: AnyMessageContent, options?: MiscMessageGenerationOptions) => Promise<proto.WebMessageInfo | undefined>;
26
28
  newsletterCreate: (name: string, description?: string) => Promise<import("../Types").NewsletterMetadata>;