gifted-baileys 1.5.0 → 1.5.5

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 (222) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1429 -684
  3. package/package.json +11 -26
  4. package/src/Defaults/baileys-version.json +3 -0
  5. package/{lib → src}/Defaults/index.js +16 -8
  6. package/src/Defaults/index.ts +131 -0
  7. package/src/Defaults/phonenumber-mcc.json +223 -0
  8. package/src/Signal/libsignal.js +180 -0
  9. package/src/Signal/libsignal.ts +141 -0
  10. package/src/Socket/Client/abstract-socket-client.ts +19 -0
  11. package/src/Socket/Client/index.ts +3 -0
  12. package/src/Socket/Client/mobile-socket-client.js +78 -0
  13. package/src/Socket/Client/mobile-socket-client.ts +66 -0
  14. package/src/Socket/Client/web-socket-client.js +75 -0
  15. package/src/Socket/Client/web-socket-client.ts +57 -0
  16. package/{lib → src}/Socket/business.js +33 -27
  17. package/src/Socket/business.ts +281 -0
  18. package/{lib → src}/Socket/chats.js +197 -178
  19. package/src/Socket/chats.ts +1030 -0
  20. package/{lib → src}/Socket/groups.js +69 -79
  21. package/src/Socket/groups.ts +356 -0
  22. package/{lib → src}/Socket/index.js +1 -4
  23. package/src/Socket/index.ts +13 -0
  24. package/{lib → src}/Socket/messages-recv.js +160 -108
  25. package/src/Socket/messages-recv.ts +985 -0
  26. package/{lib → src}/Socket/messages-send.js +183 -100
  27. package/src/Socket/messages-send.ts +871 -0
  28. package/src/Socket/newsletter.js +227 -0
  29. package/src/Socket/newsletter.ts +282 -0
  30. package/{lib → src}/Socket/registration.js +55 -63
  31. package/src/Socket/registration.ts +250 -0
  32. package/{lib → src}/Socket/socket.js +107 -66
  33. package/src/Socket/socket.ts +777 -0
  34. package/src/Store/index.ts +3 -0
  35. package/{lib → src}/Store/make-cache-manager-store.js +34 -25
  36. package/src/Store/make-cache-manager-store.ts +100 -0
  37. package/{lib → src}/Store/make-in-memory-store.js +51 -61
  38. package/src/Store/make-in-memory-store.ts +475 -0
  39. package/src/Store/make-ordered-dictionary.ts +86 -0
  40. package/{lib → src}/Store/object-repository.js +1 -1
  41. package/src/Store/object-repository.ts +32 -0
  42. package/src/Tests/test.app-state-sync.js +204 -0
  43. package/src/Tests/test.app-state-sync.ts +207 -0
  44. package/src/Tests/test.event-buffer.js +270 -0
  45. package/src/Tests/test.event-buffer.ts +319 -0
  46. package/src/Tests/test.key-store.js +76 -0
  47. package/src/Tests/test.key-store.ts +92 -0
  48. package/src/Tests/test.libsignal.js +141 -0
  49. package/src/Tests/test.libsignal.ts +186 -0
  50. package/src/Tests/test.media-download.js +93 -0
  51. package/src/Tests/test.media-download.ts +76 -0
  52. package/src/Tests/test.messages.js +33 -0
  53. package/src/Tests/test.messages.ts +37 -0
  54. package/src/Tests/utils.js +34 -0
  55. package/src/Tests/utils.ts +36 -0
  56. package/src/Types/Auth.ts +113 -0
  57. package/src/Types/Call.ts +15 -0
  58. package/src/Types/Chat.ts +106 -0
  59. package/{lib/Types/Contact.d.ts → src/Types/Contact.ts} +9 -8
  60. package/src/Types/Events.ts +93 -0
  61. package/src/Types/GroupMetadata.ts +53 -0
  62. package/{lib → src}/Types/Label.js +1 -1
  63. package/src/Types/Label.ts +36 -0
  64. package/{lib → src}/Types/LabelAssociation.js +1 -1
  65. package/{lib/Types/LabelAssociation.d.ts → src/Types/LabelAssociation.ts} +22 -16
  66. package/src/Types/Message.ts +288 -0
  67. package/src/Types/Newsletter.js +32 -0
  68. package/src/Types/Newsletter.ts +98 -0
  69. package/src/Types/Product.ts +85 -0
  70. package/src/Types/Signal.ts +68 -0
  71. package/{lib/Types/Socket.d.ts → src/Types/Socket.ts} +68 -56
  72. package/src/Types/State.ts +29 -0
  73. package/{lib → src}/Types/index.js +2 -1
  74. package/src/Types/index.ts +59 -0
  75. package/{lib → src}/Utils/auth-utils.js +95 -76
  76. package/src/Utils/auth-utils.ts +222 -0
  77. package/src/Utils/baileys-event-stream.js +92 -0
  78. package/src/Utils/baileys-event-stream.ts +66 -0
  79. package/{lib → src}/Utils/business.js +45 -17
  80. package/src/Utils/business.ts +275 -0
  81. package/{lib → src}/Utils/chat-utils.js +74 -46
  82. package/src/Utils/chat-utils.ts +860 -0
  83. package/{lib → src}/Utils/crypto.js +31 -21
  84. package/src/Utils/crypto.ts +131 -0
  85. package/src/Utils/decode-wa-message.js +211 -0
  86. package/src/Utils/decode-wa-message.ts +228 -0
  87. package/{lib → src}/Utils/event-buffer.js +13 -4
  88. package/src/Utils/event-buffer.ts +613 -0
  89. package/{lib → src}/Utils/generics.js +98 -45
  90. package/src/Utils/generics.ts +434 -0
  91. package/{lib → src}/Utils/history.js +39 -10
  92. package/src/Utils/history.ts +112 -0
  93. package/src/Utils/index.ts +17 -0
  94. package/{lib → src}/Utils/link-preview.js +54 -17
  95. package/src/Utils/link-preview.ts +122 -0
  96. package/src/Utils/logger.ts +3 -0
  97. package/src/Utils/lt-hash.ts +61 -0
  98. package/{lib → src}/Utils/make-mutex.js +13 -4
  99. package/src/Utils/make-mutex.ts +44 -0
  100. package/{lib → src}/Utils/messages-media.js +296 -192
  101. package/src/Utils/messages-media.ts +847 -0
  102. package/{lib → src}/Utils/messages.js +124 -113
  103. package/src/Utils/messages.ts +956 -0
  104. package/{lib → src}/Utils/noise-handler.js +16 -3
  105. package/src/Utils/noise-handler.ts +197 -0
  106. package/{lib → src}/Utils/process-message.js +33 -29
  107. package/src/Utils/process-message.ts +414 -0
  108. package/{lib → src}/Utils/signal.js +23 -14
  109. package/src/Utils/signal.ts +177 -0
  110. package/{lib → src}/Utils/use-multi-file-auth-state.js +28 -19
  111. package/src/Utils/use-multi-file-auth-state.ts +90 -0
  112. package/{lib → src}/Utils/validate-connection.js +25 -42
  113. package/src/Utils/validate-connection.ts +238 -0
  114. package/src/WABinary/constants.ts +42 -0
  115. package/{lib → src}/WABinary/decode.js +17 -7
  116. package/src/WABinary/decode.ts +265 -0
  117. package/{lib → src}/WABinary/encode.js +17 -7
  118. package/src/WABinary/encode.ts +236 -0
  119. package/{lib → src}/WABinary/generic-utils.js +2 -2
  120. package/src/WABinary/generic-utils.ts +121 -0
  121. package/src/WABinary/index.ts +5 -0
  122. package/{lib → src}/WABinary/jid-utils.js +4 -1
  123. package/src/WABinary/jid-utils.ts +68 -0
  124. package/src/WABinary/types.ts +17 -0
  125. package/src/WAM/BinaryInfo.js +13 -0
  126. package/src/WAM/BinaryInfo.ts +12 -0
  127. package/src/WAM/constants.js +15350 -0
  128. package/src/WAM/constants.ts +15382 -0
  129. package/src/WAM/encode.js +155 -0
  130. package/src/WAM/encode.ts +174 -0
  131. package/src/WAM/index.js +19 -0
  132. package/src/WAM/index.ts +3 -0
  133. package/src/gifted +1 -0
  134. package/{lib → src}/index.js +1 -0
  135. package/src/index.ts +13 -0
  136. package/lib/Defaults/baileys-version.json +0 -3
  137. package/lib/Defaults/index.d.ts +0 -284
  138. package/lib/Defaults/phonenumber-mcc.json +0 -223
  139. package/lib/Signal/libsignal.d.ts +0 -3
  140. package/lib/Signal/libsignal.js +0 -152
  141. package/lib/Socket/Client/abstract-socket-client.d.ts +0 -17
  142. package/lib/Socket/Client/index.d.ts +0 -3
  143. package/lib/Socket/Client/mobile-socket-client.d.ts +0 -13
  144. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  145. package/lib/Socket/Client/web-socket-client.d.ts +0 -12
  146. package/lib/Socket/Client/web-socket-client.js +0 -62
  147. package/lib/Socket/business.d.ts +0 -135
  148. package/lib/Socket/chats.d.ts +0 -79
  149. package/lib/Socket/groups.d.ts +0 -113
  150. package/lib/Socket/index.d.ts +0 -137
  151. package/lib/Socket/messages-recv.d.ts +0 -124
  152. package/lib/Socket/messages-send.d.ts +0 -119
  153. package/lib/Socket/registration.d.ts +0 -232
  154. package/lib/Socket/socket.d.ts +0 -42
  155. package/lib/Store/index.d.ts +0 -3
  156. package/lib/Store/make-cache-manager-store.d.ts +0 -13
  157. package/lib/Store/make-in-memory-store.d.ts +0 -117
  158. package/lib/Store/make-ordered-dictionary.d.ts +0 -13
  159. package/lib/Store/object-repository.d.ts +0 -10
  160. package/lib/Types/Auth.d.ts +0 -108
  161. package/lib/Types/Call.d.ts +0 -13
  162. package/lib/Types/Chat.d.ts +0 -102
  163. package/lib/Types/Events.d.ts +0 -157
  164. package/lib/Types/GroupMetadata.d.ts +0 -52
  165. package/lib/Types/Label.d.ts +0 -35
  166. package/lib/Types/Message.d.ts +0 -261
  167. package/lib/Types/Product.d.ts +0 -78
  168. package/lib/Types/Signal.d.ts +0 -57
  169. package/lib/Types/State.d.ts +0 -27
  170. package/lib/Types/index.d.ts +0 -56
  171. package/lib/Utils/auth-utils.d.ts +0 -18
  172. package/lib/Utils/baileys-event-stream.d.ts +0 -16
  173. package/lib/Utils/baileys-event-stream.js +0 -63
  174. package/lib/Utils/business.d.ts +0 -22
  175. package/lib/Utils/chat-utils.d.ts +0 -71
  176. package/lib/Utils/crypto.d.ts +0 -41
  177. package/lib/Utils/decode-wa-message.d.ts +0 -19
  178. package/lib/Utils/decode-wa-message.js +0 -174
  179. package/lib/Utils/event-buffer.d.ts +0 -35
  180. package/lib/Utils/generics.d.ts +0 -94
  181. package/lib/Utils/history.d.ts +0 -15
  182. package/lib/Utils/index.d.ts +0 -17
  183. package/lib/Utils/link-preview.d.ts +0 -21
  184. package/lib/Utils/logger.d.ts +0 -4
  185. package/lib/Utils/lt-hash.d.ts +0 -12
  186. package/lib/Utils/make-mutex.d.ts +0 -7
  187. package/lib/Utils/messages-media.d.ts +0 -107
  188. package/lib/Utils/messages.d.ts +0 -76
  189. package/lib/Utils/noise-handler.d.ts +0 -20
  190. package/lib/Utils/process-message.d.ts +0 -41
  191. package/lib/Utils/signal.d.ts +0 -32
  192. package/lib/Utils/use-multi-file-auth-state.d.ts +0 -12
  193. package/lib/Utils/validate-connection.d.ts +0 -11
  194. package/lib/WABinary/constants.d.ts +0 -27
  195. package/lib/WABinary/decode.d.ts +0 -7
  196. package/lib/WABinary/encode.d.ts +0 -3
  197. package/lib/WABinary/generic-utils.d.ts +0 -15
  198. package/lib/WABinary/index.d.ts +0 -5
  199. package/lib/WABinary/jid-utils.d.ts +0 -29
  200. package/lib/WABinary/types.d.ts +0 -18
  201. package/lib/index.d.ts +0 -10
  202. /package/{lib → src}/Socket/Client/abstract-socket-client.js +0 -0
  203. /package/{lib → src}/Socket/Client/index.js +0 -0
  204. /package/{lib → src}/Store/index.js +0 -0
  205. /package/{lib → src}/Store/make-ordered-dictionary.js +0 -0
  206. /package/{lib → src}/Types/Auth.js +0 -0
  207. /package/{lib → src}/Types/Call.js +0 -0
  208. /package/{lib → src}/Types/Chat.js +0 -0
  209. /package/{lib → src}/Types/Contact.js +0 -0
  210. /package/{lib → src}/Types/Events.js +0 -0
  211. /package/{lib → src}/Types/GroupMetadata.js +0 -0
  212. /package/{lib → src}/Types/Message.js +0 -0
  213. /package/{lib → src}/Types/Product.js +0 -0
  214. /package/{lib → src}/Types/Signal.js +0 -0
  215. /package/{lib → src}/Types/Socket.js +0 -0
  216. /package/{lib → src}/Types/State.js +0 -0
  217. /package/{lib → src}/Utils/index.js +0 -0
  218. /package/{lib → src}/Utils/logger.js +0 -0
  219. /package/{lib → src}/Utils/lt-hash.js +0 -0
  220. /package/{lib → src}/WABinary/constants.js +0 -0
  221. /package/{lib → src}/WABinary/index.js +0 -0
  222. /package/{lib → src}/WABinary/types.js +0 -0
@@ -0,0 +1,250 @@
1
+ /* eslint-disable camelcase */
2
+ import axios, { AxiosRequestConfig } from 'axios'
3
+ import { MOBILE_REGISTRATION_ENDPOINT, MOBILE_TOKEN, MOBILE_USERAGENT, REGISTRATION_PUBLIC_KEY } from '../Defaults'
4
+ import { KeyPair, SignedKeyPair, SocketConfig } from '../Types'
5
+ import { aesEncryptGCM, Curve, md5 } from '../Utils/crypto'
6
+ import { jidEncode } from '../WABinary'
7
+ import { makeBusinessSocket } from './business'
8
+
9
+ function urlencode(str: string) {
10
+ return str.replace(/-/g, '%2d').replace(/_/g, '%5f').replace(/~/g, '%7e')
11
+ }
12
+
13
+ const validRegistrationOptions = (config: RegistrationOptions) => config?.phoneNumberCountryCode &&
14
+ config.phoneNumberNationalNumber &&
15
+ config.phoneNumberMobileCountryCode
16
+
17
+ export const makeRegistrationSocket = (config: SocketConfig) => {
18
+ const sock = makeBusinessSocket(config)
19
+
20
+ const register = async(code: string) => {
21
+ if(!validRegistrationOptions(config.auth.creds.registration)) {
22
+ throw new Error('please specify the registration options')
23
+ }
24
+
25
+ const result = await mobileRegister({ ...sock.authState.creds, ...sock.authState.creds.registration as RegistrationOptions, code }, config.options)
26
+
27
+ sock.authState.creds.me = {
28
+ id: jidEncode(result.login!, 's.whatsapp.net'),
29
+ name: '~'
30
+ }
31
+
32
+ sock.authState.creds.registered = true
33
+ sock.ev.emit('creds.update', sock.authState.creds)
34
+
35
+ return result
36
+ }
37
+
38
+ const requestRegistrationCode = async(registrationOptions?: RegistrationOptions) => {
39
+ registrationOptions = registrationOptions || config.auth.creds.registration
40
+ if(!validRegistrationOptions(registrationOptions)) {
41
+ throw new Error('Invalid registration options')
42
+ }
43
+
44
+ sock.authState.creds.registration = registrationOptions
45
+
46
+ sock.ev.emit('creds.update', sock.authState.creds)
47
+
48
+ return mobileRegisterCode({ ...config.auth.creds, ...registrationOptions }, config.options)
49
+ }
50
+
51
+ return {
52
+ ...sock,
53
+ register,
54
+ requestRegistrationCode,
55
+ }
56
+ }
57
+
58
+ // Backup_token: Base64.getEncoder().encodeToString(Arrays.copyOfRange(Base64.getDecoder().decode(UUID.randomUUID().toString().replace('-','')),0,15))
59
+
60
+ export interface RegistrationData {
61
+ registrationId: number
62
+ signedPreKey: SignedKeyPair
63
+ noiseKey: KeyPair
64
+ signedIdentityKey: KeyPair
65
+ identityId: Buffer
66
+ phoneId: string
67
+ deviceId: string
68
+ backupToken: Buffer
69
+ }
70
+
71
+ export interface RegistrationOptions {
72
+ /** your phone number */
73
+ phoneNumber?: string
74
+ /** the country code of your phone number */
75
+ phoneNumberCountryCode: string
76
+ /** your phone number without country code */
77
+ phoneNumberNationalNumber: string
78
+ /** the country code of your mobile network
79
+ * @see {@link https://de.wikipedia.org/wiki/Mobile_Country_Code}
80
+ */
81
+ phoneNumberMobileCountryCode: string
82
+ /** the network code of your mobile network
83
+ * @see {@link https://de.wikipedia.org/wiki/Mobile_Network_Code}
84
+ */
85
+ phoneNumberMobileNetworkCode: string
86
+ /**
87
+ * How to send the one time code
88
+ */
89
+ method?: 'sms' | 'voice' | 'captcha'
90
+ /**
91
+ * The captcha code if it was requested
92
+ */
93
+ captcha?: string
94
+ }
95
+
96
+ export type RegistrationParams = RegistrationData & RegistrationOptions
97
+
98
+ function convertBufferToUrlHex(buffer: Buffer) {
99
+ var id = ''
100
+
101
+ buffer.forEach((x) => {
102
+ // encode random identity_id buffer as percentage url encoding
103
+ id += `%${x.toString(16).padStart(2, '0').toLowerCase()}`
104
+ })
105
+
106
+ return id
107
+ }
108
+
109
+ export function registrationParams(params: RegistrationParams) {
110
+ const e_regid = Buffer.alloc(4)
111
+ e_regid.writeInt32BE(params.registrationId)
112
+
113
+ const e_skey_id = Buffer.alloc(3)
114
+ e_skey_id.writeInt16BE(params.signedPreKey.keyId)
115
+
116
+ params.phoneNumberCountryCode = params.phoneNumberCountryCode.replace('+', '').trim()
117
+ params.phoneNumberNationalNumber = params.phoneNumberNationalNumber.replace(/[/-\s)(]/g, '').trim()
118
+
119
+ return {
120
+ cc: params.phoneNumberCountryCode,
121
+ in: params.phoneNumberNationalNumber,
122
+ Rc: '0',
123
+ lg: 'en',
124
+ lc: 'GB',
125
+ mistyped: '6',
126
+ authkey: Buffer.from(params.noiseKey.public).toString('base64url'),
127
+ e_regid: e_regid.toString('base64url'),
128
+ e_keytype: 'BQ',
129
+ e_ident: Buffer.from(params.signedIdentityKey.public).toString('base64url'),
130
+ // e_skey_id: e_skey_id.toString('base64url'),
131
+ e_skey_id: 'AAAA',
132
+ e_skey_val: Buffer.from(params.signedPreKey.keyPair.public).toString('base64url'),
133
+ e_skey_sig: Buffer.from(params.signedPreKey.signature).toString('base64url'),
134
+ fdid: params.phoneId,
135
+ network_ratio_type: '1',
136
+ expid: params.deviceId,
137
+ simnum: '1',
138
+ hasinrc: '1',
139
+ pid: Math.floor(Math.random() * 1000).toString(),
140
+ id: convertBufferToUrlHex(params.identityId),
141
+ backup_token: convertBufferToUrlHex(params.backupToken),
142
+ token: md5(Buffer.concat([MOBILE_TOKEN, Buffer.from(params.phoneNumberNationalNumber)])).toString('hex'),
143
+ fraud_checkpoint_code: params.captcha,
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Requests a registration code for the given phone number.
149
+ */
150
+ export function mobileRegisterCode(params: RegistrationParams, fetchOptions?: AxiosRequestConfig) {
151
+ return mobileRegisterFetch('/code', {
152
+ params: {
153
+ ...registrationParams(params),
154
+ mcc: `${params.phoneNumberMobileCountryCode}`.padStart(3, '0'),
155
+ mnc: `${params.phoneNumberMobileNetworkCode || '001'}`.padStart(3, '0'),
156
+ sim_mcc: '000',
157
+ sim_mnc: '000',
158
+ method: params?.method || 'sms',
159
+ reason: '',
160
+ hasav: '1'
161
+ },
162
+ ...fetchOptions,
163
+ })
164
+ }
165
+
166
+ export function mobileRegisterExists(params: RegistrationParams, fetchOptions?: AxiosRequestConfig) {
167
+ return mobileRegisterFetch('/exist', {
168
+ params: registrationParams(params),
169
+ ...fetchOptions
170
+ })
171
+ }
172
+
173
+ /**
174
+ * Registers the phone number on whatsapp with the received OTP code.
175
+ */
176
+ export async function mobileRegister(params: RegistrationParams & { code: string }, fetchOptions?: AxiosRequestConfig) {
177
+ //const result = await mobileRegisterFetch(`/reg_onboard_abprop?cc=${params.phoneNumberCountryCode}&in=${params.phoneNumberNationalNumber}&rc=0`)
178
+
179
+ return mobileRegisterFetch('/register', {
180
+ params: { ...registrationParams(params), code: params.code.replace('-', '') },
181
+ ...fetchOptions,
182
+ })
183
+ }
184
+
185
+ /**
186
+ * Encrypts the given string as AEAD aes-256-gcm with the public whatsapp key and a random keypair.
187
+ */
188
+ export function mobileRegisterEncrypt(data: string) {
189
+ const keypair = Curve.generateKeyPair()
190
+ const key = Curve.sharedKey(keypair.private, REGISTRATION_PUBLIC_KEY)
191
+
192
+ const buffer = aesEncryptGCM(Buffer.from(data), new Uint8Array(key), Buffer.alloc(12), Buffer.alloc(0))
193
+
194
+ return Buffer.concat([Buffer.from(keypair.public), buffer]).toString('base64url')
195
+ }
196
+
197
+ export async function mobileRegisterFetch(path: string, opts: AxiosRequestConfig = {}) {
198
+ let url = `${MOBILE_REGISTRATION_ENDPOINT}${path}`
199
+
200
+ if(opts.params) {
201
+ const parameter = [] as string[]
202
+
203
+ for(const param in opts.params) {
204
+ if(opts.params[param] !== null && opts.params[param] !== undefined) {
205
+ parameter.push(param + '=' + urlencode(opts.params[param]))
206
+ }
207
+ }
208
+
209
+ url += `?${parameter.join('&')}`
210
+ delete opts.params
211
+ }
212
+
213
+ if(!opts.headers) {
214
+ opts.headers = {}
215
+ }
216
+
217
+ opts.headers['User-Agent'] = MOBILE_USERAGENT
218
+
219
+ const response = await axios(url, opts)
220
+
221
+ var json = response.data
222
+
223
+ if(response.status > 300 || json.reason) {
224
+ throw json
225
+ }
226
+
227
+ if(json.status && !['ok', 'sent'].includes(json.status)) {
228
+ throw json
229
+ }
230
+
231
+ return json as ExistsResponse
232
+ }
233
+
234
+
235
+ export interface ExistsResponse {
236
+ status: 'fail' | 'sent'
237
+ voice_length?: number
238
+ voice_wait?: number
239
+ sms_length?: number
240
+ sms_wait?: number
241
+ reason?: 'incorrect' | 'missing_param' | 'code_checkpoint'
242
+ login?: string
243
+ flash_type?: number
244
+ ab_hash?: string
245
+ ab_key?: string
246
+ exp_cfg?: string
247
+ lid?: string
248
+ image_blob?: string
249
+ audio_blob?: string
250
+ }
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.makeSocket = void 0;
4
13
  const boom_1 = require("@hapi/boom");
@@ -18,12 +27,16 @@ const Client_1 = require("./Client");
18
27
  * - query phone connection
19
28
  */
20
29
  const makeSocket = (config) => {
30
+ var _a, _b;
21
31
  const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository, } = config;
22
32
  let url = typeof waWebSocketUrl === 'string' ? new url_1.URL(waWebSocketUrl) : waWebSocketUrl;
23
33
  config.mobile = config.mobile || url.protocol === 'tcp:';
24
34
  if (config.mobile && url.protocol !== 'tcp:') {
25
35
  url = new url_1.URL(`tcp://${Defaults_1.MOBILE_ENDPOINT}:${Defaults_1.MOBILE_PORT}`);
26
36
  }
37
+ if (!config.mobile && url.protocol === 'wss' && ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.routingInfo)) {
38
+ url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'));
39
+ }
27
40
  const ws = config.socket ? config.socket : config.mobile ? new Client_1.MobileSocketClient(url, config) : new Client_1.WebSocketClient(url, config);
28
41
  ws.connect();
29
42
  const ev = (0, Utils_1.makeEventBuffer)(logger);
@@ -34,7 +47,8 @@ const makeSocket = (config) => {
34
47
  keyPair: ephemeralKeyPair,
35
48
  NOISE_HEADER: config.mobile ? Defaults_1.MOBILE_NOISE_HEADER : Defaults_1.NOISE_WA_HEADER,
36
49
  mobile: config.mobile,
37
- logger
50
+ logger,
51
+ routingInfo: (_b = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _b === void 0 ? void 0 : _b.routingInfo
38
52
  });
39
53
  const { creds } = authState;
40
54
  // add transaction capability
@@ -49,25 +63,25 @@ const makeSocket = (config) => {
49
63
  const generateMessageTag = () => `${uqTagId}${epoch++}`;
50
64
  const sendPromise = (0, util_1.promisify)(ws.send);
51
65
  /** send a raw buffer */
52
- const sendRawMessage = async (data) => {
66
+ const sendRawMessage = (data) => __awaiter(void 0, void 0, void 0, function* () {
53
67
  if (!ws.isOpen) {
54
68
  throw new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed });
55
69
  }
56
70
  const bytes = noise.encodeFrame(data);
57
- await (0, Utils_1.promiseTimeout)(connectTimeoutMs, async (resolve, reject) => {
71
+ yield (0, Utils_1.promiseTimeout)(connectTimeoutMs, (resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
58
72
  try {
59
- await sendPromise.call(ws, bytes);
73
+ yield sendPromise.call(ws, bytes);
60
74
  resolve();
61
75
  }
62
76
  catch (error) {
63
77
  reject(error);
64
78
  }
65
- });
66
- };
79
+ }));
80
+ });
67
81
  /** send a binary node */
68
82
  const sendNode = (frame) => {
69
83
  if (logger.level === 'trace') {
70
- logger.trace((0, WABinary_1.binaryNodeToString)(frame), 'xml send');
84
+ logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'xml send' });
71
85
  }
72
86
  const buff = (0, WABinary_1.encodeBinaryNode)(frame);
73
87
  return sendRawMessage(buff);
@@ -77,7 +91,7 @@ const makeSocket = (config) => {
77
91
  logger.error({ err }, `unexpected error in '${msg}'`);
78
92
  };
79
93
  /** await the next incoming message */
80
- const awaitNextMessage = async (sendMsg) => {
94
+ const awaitNextMessage = (sendMsg) => __awaiter(void 0, void 0, void 0, function* () {
81
95
  if (!ws.isOpen) {
82
96
  throw new boom_1.Boom('Connection Closed', {
83
97
  statusCode: Types_1.DisconnectReason.connectionClosed
@@ -101,17 +115,17 @@ const makeSocket = (config) => {
101
115
  sendRawMessage(sendMsg).catch(onClose);
102
116
  }
103
117
  return result;
104
- };
118
+ });
105
119
  /**
106
120
  * Wait for a message with a certain tag to be received
107
121
  * @param msgId the message tag to await
108
122
  * @param timeoutMs timeout after which the promise will reject
109
123
  */
110
- const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
124
+ const waitForMessage = (msgId_1, ...args_1) => __awaiter(void 0, [msgId_1, ...args_1], void 0, function* (msgId, timeoutMs = defaultQueryTimeoutMs) {
111
125
  let onRecv;
112
126
  let onErr;
113
127
  try {
114
- return await (0, Utils_1.promiseTimeout)(timeoutMs, (resolve, reject) => {
128
+ return yield (0, Utils_1.promiseTimeout)(timeoutMs, (resolve, reject) => {
115
129
  onRecv = resolve;
116
130
  onErr = err => {
117
131
  reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
@@ -126,30 +140,30 @@ const makeSocket = (config) => {
126
140
  ws.off('close', onErr); // if the socket closes, you'll never receive the message
127
141
  ws.off('error', onErr);
128
142
  }
129
- };
143
+ });
130
144
  /** send a query, and wait for its response. auto-generates message ID if not provided */
131
- const query = async (node, timeoutMs) => {
145
+ const query = (node, timeoutMs) => __awaiter(void 0, void 0, void 0, function* () {
132
146
  if (!node.attrs.id) {
133
147
  node.attrs.id = generateMessageTag();
134
148
  }
135
149
  const msgId = node.attrs.id;
136
150
  const wait = waitForMessage(msgId, timeoutMs);
137
- await sendNode(node);
138
- const result = await wait;
151
+ yield sendNode(node);
152
+ const result = yield wait;
139
153
  if ('tag' in result) {
140
154
  (0, WABinary_1.assertNodeErrorFree)(result);
141
155
  }
142
156
  return result;
143
- };
157
+ });
144
158
  /** connection handshake */
145
- const validateConnection = async () => {
159
+ const validateConnection = () => __awaiter(void 0, void 0, void 0, function* () {
146
160
  let helloMsg = {
147
161
  clientHello: { ephemeral: ephemeralKeyPair.public }
148
162
  };
149
163
  helloMsg = WAProto_1.proto.HandshakeMessage.fromObject(helloMsg);
150
164
  logger.info({ browser, helloMsg }, 'connected to WA');
151
165
  const init = WAProto_1.proto.HandshakeMessage.encode(helloMsg).finish();
152
- const result = await awaitNextMessage(init);
166
+ const result = yield awaitNextMessage(init);
153
167
  const handshake = WAProto_1.proto.HandshakeMessage.decode(result);
154
168
  logger.trace({ handshake }, 'handshake recv from WA');
155
169
  const keyEnc = noise.processHandshake(handshake, creds.noiseKey);
@@ -166,7 +180,7 @@ const makeSocket = (config) => {
166
180
  logger.info({ node }, 'logging in...');
167
181
  }
168
182
  const payloadEnc = noise.encrypt(WAProto_1.proto.ClientPayload.encode(node).finish());
169
- await sendRawMessage(WAProto_1.proto.HandshakeMessage.encode({
183
+ yield sendRawMessage(WAProto_1.proto.HandshakeMessage.encode({
170
184
  clientFinish: {
171
185
  static: keyEnc,
172
186
  payload: payloadEnc,
@@ -174,9 +188,9 @@ const makeSocket = (config) => {
174
188
  }).finish());
175
189
  noise.finishInit();
176
190
  startKeepAliveRequest();
177
- };
178
- const getAvailablePreKeysOnServer = async () => {
179
- const result = await query({
191
+ });
192
+ const getAvailablePreKeysOnServer = () => __awaiter(void 0, void 0, void 0, function* () {
193
+ const result = yield query({
180
194
  tag: 'iq',
181
195
  attrs: {
182
196
  id: generateMessageTag(),
@@ -190,25 +204,25 @@ const makeSocket = (config) => {
190
204
  });
191
205
  const countChild = (0, WABinary_1.getBinaryNodeChild)(result, 'count');
192
206
  return +countChild.attrs.value;
193
- };
207
+ });
194
208
  /** generates and uploads a set of pre-keys to the server */
195
- const uploadPreKeys = async (count = Defaults_1.INITIAL_PREKEY_COUNT) => {
196
- await keys.transaction(async () => {
209
+ const uploadPreKeys = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (count = Defaults_1.INITIAL_PREKEY_COUNT) {
210
+ yield keys.transaction(() => __awaiter(void 0, void 0, void 0, function* () {
197
211
  logger.info({ count }, 'uploading pre-keys');
198
- const { update, node } = await (0, Utils_1.getNextPreKeysNode)({ creds, keys }, count);
199
- await query(node);
212
+ const { update, node } = yield (0, Utils_1.getNextPreKeysNode)({ creds, keys }, count);
213
+ yield query(node);
200
214
  ev.emit('creds.update', update);
201
215
  logger.info({ count }, 'uploaded pre-keys');
202
- });
203
- };
204
- const uploadPreKeysToServerIfRequired = async () => {
205
- const preKeyCount = await getAvailablePreKeysOnServer();
216
+ }));
217
+ });
218
+ const uploadPreKeysToServerIfRequired = () => __awaiter(void 0, void 0, void 0, function* () {
219
+ const preKeyCount = yield getAvailablePreKeysOnServer();
206
220
  logger.info(`${preKeyCount} pre-keys found on server`);
207
221
  if (preKeyCount <= Defaults_1.MIN_PREKEY_COUNT) {
208
- await uploadPreKeys();
222
+ yield uploadPreKeys();
209
223
  }
210
- };
211
- const onMessageRecieved = (data) => {
224
+ });
225
+ const onMessageReceived = (data) => {
212
226
  noise.decodeFrame(data, frame => {
213
227
  var _a;
214
228
  // reset ping timeout
@@ -219,7 +233,7 @@ const makeSocket = (config) => {
219
233
  if (!(frame instanceof Uint8Array)) {
220
234
  const msgId = frame.attrs.id;
221
235
  if (logger.level === 'trace') {
222
- logger.trace((0, WABinary_1.binaryNodeToString)(frame), 'recv xml');
236
+ logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'recv xml' });
223
237
  }
224
238
  /* Check if this is a response to a message we sent */
225
239
  anyTriggered = ws.emit(`${Defaults_1.DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered;
@@ -268,7 +282,7 @@ const makeSocket = (config) => {
268
282
  });
269
283
  ev.removeAllListeners('connection.update');
270
284
  };
271
- const waitForSocketOpen = async () => {
285
+ const waitForSocketOpen = () => __awaiter(void 0, void 0, void 0, function* () {
272
286
  if (ws.isOpen) {
273
287
  return;
274
288
  }
@@ -277,7 +291,7 @@ const makeSocket = (config) => {
277
291
  }
278
292
  let onOpen;
279
293
  let onClose;
280
- await new Promise((resolve, reject) => {
294
+ yield new Promise((resolve, reject) => {
281
295
  onOpen = () => resolve(undefined);
282
296
  onClose = mapWebSocketError(reject);
283
297
  ws.on('open', onOpen);
@@ -289,7 +303,7 @@ const makeSocket = (config) => {
289
303
  ws.off('close', onClose);
290
304
  ws.off('error', onClose);
291
305
  });
292
- };
306
+ });
293
307
  const startKeepAliveRequest = () => (keepAliveReq = setInterval(() => {
294
308
  if (!lastDateRecv) {
295
309
  lastDateRecv = new Date();
@@ -335,11 +349,11 @@ const makeSocket = (config) => {
335
349
  ]
336
350
  }));
337
351
  /** logout & invalidate connection */
338
- const logout = async (msg) => {
352
+ const logout = (msg) => __awaiter(void 0, void 0, void 0, function* () {
339
353
  var _a;
340
354
  const jid = (_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id;
341
355
  if (jid) {
342
- await sendNode({
356
+ yield sendNode({
343
357
  tag: 'iq',
344
358
  attrs: {
345
359
  to: WABinary_1.S_WHATSAPP_NET,
@@ -359,15 +373,15 @@ const makeSocket = (config) => {
359
373
  });
360
374
  }
361
375
  end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }));
362
- };
363
- const requestPairingCode = async (phoneNumber) => {
376
+ });
377
+ const requestPairingCode = (phoneNumber) => __awaiter(void 0, void 0, void 0, function* () {
364
378
  authState.creds.pairingCode = (0, Utils_1.bytesToCrockford)((0, crypto_1.randomBytes)(5));
365
379
  authState.creds.me = {
366
380
  id: (0, WABinary_1.jidEncode)(phoneNumber, 's.whatsapp.net'),
367
381
  name: '~'
368
382
  };
369
383
  ev.emit('creds.update', authState.creds);
370
- await sendNode({
384
+ yield sendNode({
371
385
  tag: 'iq',
372
386
  attrs: {
373
387
  to: WABinary_1.S_WHATSAPP_NET,
@@ -388,7 +402,7 @@ const makeSocket = (config) => {
388
402
  {
389
403
  tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
390
404
  attrs: {},
391
- content: await generatePairingKey()
405
+ content: yield generatePairingKey()
392
406
  },
393
407
  {
394
408
  tag: 'companion_server_auth_key_pub',
@@ -415,30 +429,49 @@ const makeSocket = (config) => {
415
429
  ]
416
430
  });
417
431
  return authState.creds.pairingCode;
418
- };
419
- async function generatePairingKey() {
420
- const salt = (0, crypto_1.randomBytes)(32);
421
- const randomIv = (0, crypto_1.randomBytes)(16);
422
- const key = (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
423
- const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
424
- return Buffer.concat([salt, randomIv, ciphered]);
432
+ });
433
+ function generatePairingKey() {
434
+ return __awaiter(this, void 0, void 0, function* () {
435
+ const salt = (0, crypto_1.randomBytes)(32);
436
+ const randomIv = (0, crypto_1.randomBytes)(16);
437
+ const key = (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
438
+ const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
439
+ return Buffer.concat([salt, randomIv, ciphered]);
440
+ });
425
441
  }
426
- ws.on('message', onMessageRecieved);
427
- ws.on('open', async () => {
442
+ const sendWAMBuffer = (wamBuffer) => {
443
+ return query({
444
+ tag: 'iq',
445
+ attrs: {
446
+ to: WABinary_1.S_WHATSAPP_NET,
447
+ id: generateMessageTag(),
448
+ xmlns: 'w:stats'
449
+ },
450
+ content: [
451
+ {
452
+ tag: 'add',
453
+ attrs: {},
454
+ content: wamBuffer
455
+ }
456
+ ]
457
+ });
458
+ };
459
+ ws.on('message', onMessageReceived);
460
+ ws.on('open', () => __awaiter(void 0, void 0, void 0, function* () {
428
461
  try {
429
- await validateConnection();
462
+ yield validateConnection();
430
463
  }
431
464
  catch (err) {
432
465
  logger.error({ err }, 'error in validating connection');
433
466
  end(err);
434
467
  }
435
- });
468
+ }));
436
469
  ws.on('error', mapWebSocketError(end));
437
470
  ws.on('close', () => end(new boom_1.Boom('Connection Terminated', { statusCode: Types_1.DisconnectReason.connectionClosed })));
438
471
  // the server terminated the connection
439
472
  ws.on('CB:xmlstreamend', () => end(new boom_1.Boom('Connection Terminated by Server', { statusCode: Types_1.DisconnectReason.connectionClosed })));
440
473
  // QR gen
441
- ws.on('CB:iq,type:set,pair-device', async (stanza) => {
474
+ ws.on('CB:iq,type:set,pair-device', (stanza) => __awaiter(void 0, void 0, void 0, function* () {
442
475
  const iq = {
443
476
  tag: 'iq',
444
477
  attrs: {
@@ -447,7 +480,7 @@ const makeSocket = (config) => {
447
480
  id: stanza.attrs.id,
448
481
  }
449
482
  };
450
- await sendNode(iq);
483
+ yield sendNode(iq);
451
484
  const pairDeviceNode = (0, WABinary_1.getBinaryNodeChild)(stanza, 'pair-device');
452
485
  const refNodes = (0, WABinary_1.getBinaryNodeChildren)(pairDeviceNode, 'ref');
453
486
  const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64');
@@ -470,32 +503,32 @@ const makeSocket = (config) => {
470
503
  qrMs = qrTimeout || 20000; // shorter subsequent qrs
471
504
  };
472
505
  genPairQR();
473
- });
506
+ }));
474
507
  // device paired for the first time
475
508
  // if device pairs successfully, the server asks to restart the connection
476
- ws.on('CB:iq,,pair-success', async (stanza) => {
509
+ ws.on('CB:iq,,pair-success', (stanza) => __awaiter(void 0, void 0, void 0, function* () {
477
510
  logger.debug('pair success recv');
478
511
  try {
479
512
  const { reply, creds: updatedCreds } = (0, Utils_1.configureSuccessfulPairing)(stanza, creds);
480
513
  logger.info({ me: updatedCreds.me, platform: updatedCreds.platform }, 'pairing configured successfully, expect to restart the connection...');
481
514
  ev.emit('creds.update', updatedCreds);
482
515
  ev.emit('connection.update', { isNewLogin: true, qr: undefined });
483
- await sendNode(reply);
516
+ yield sendNode(reply);
484
517
  }
485
518
  catch (error) {
486
519
  logger.info({ trace: error.stack }, 'error in pairing');
487
520
  end(error);
488
521
  }
489
- });
522
+ }));
490
523
  // login complete
491
- ws.on('CB:success', async (node) => {
492
- await uploadPreKeysToServerIfRequired();
493
- await sendPassiveIq('active');
524
+ ws.on('CB:success', (node) => __awaiter(void 0, void 0, void 0, function* () {
525
+ yield uploadPreKeysToServerIfRequired();
526
+ yield sendPassiveIq('active');
494
527
  logger.info('opened connection to WA');
495
528
  clearTimeout(qrTimer); // will never happen in all likelyhood -- but just in case WA sends success on first try
496
- ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
529
+ ev.emit('creds.update', { me: Object.assign(Object.assign({}, authState.creds.me), { lid: node.attrs.lid }) });
497
530
  ev.emit('connection.update', { connection: 'open' });
498
- });
531
+ }));
499
532
  ws.on('CB:stream:error', (node) => {
500
533
  logger.error({ node }, 'stream errored out');
501
534
  const { reason, statusCode } = (0, Utils_1.getErrorCodeFromStreamError)(node);
@@ -509,6 +542,13 @@ const makeSocket = (config) => {
509
542
  ws.on('CB:ib,,downgrade_webclient', () => {
510
543
  end(new boom_1.Boom('Multi-device beta not joined', { statusCode: Types_1.DisconnectReason.multideviceMismatch }));
511
544
  });
545
+ ws.on('CB:ib,,edge_routing', (node) => {
546
+ const edgeRoutingNode = (0, WABinary_1.getBinaryNodeChild)(node, 'edge_routing');
547
+ const routingInfo = (0, WABinary_1.getBinaryNodeChild)(edgeRoutingNode, 'routing_info');
548
+ if (routingInfo === null || routingInfo === void 0 ? void 0 : routingInfo.content) {
549
+ authState.creds.routingInfo = Buffer.from(routingInfo === null || routingInfo === void 0 ? void 0 : routingInfo.content);
550
+ }
551
+ });
512
552
  let didStartBuffer = false;
513
553
  process.nextTick(() => {
514
554
  var _a;
@@ -574,6 +614,7 @@ const makeSocket = (config) => {
574
614
  requestPairingCode,
575
615
  /** Waits for the connection to WA to reach a state */
576
616
  waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev),
617
+ sendWAMBuffer,
577
618
  };
578
619
  };
579
620
  exports.makeSocket = makeSocket;