dcodeindra-baileyspro 2.3.9

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 (286) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2534 -0
  3. package/WAProto/Adv/Adv.d.ts +518 -0
  4. package/WAProto/Adv/Adv.js +1734 -0
  5. package/WAProto/Adv/Adv.proto +36 -0
  6. package/WAProto/BotMetadata/BotMetadata.d.ts +5745 -0
  7. package/WAProto/BotMetadata/BotMetadata.js +16291 -0
  8. package/WAProto/BotMetadata/BotMetadata.proto +463 -0
  9. package/WAProto/Cert/Cert.d.ts +497 -0
  10. package/WAProto/Cert/Cert.js +1503 -0
  11. package/WAProto/Cert/Cert.proto +28 -0
  12. package/WAProto/ChatLockSettings/ChatLockSettings.d.ts +391 -0
  13. package/WAProto/ChatLockSettings/ChatLockSettings.js +1155 -0
  14. package/WAProto/ChatLockSettings/ChatLockSettings.proto +7 -0
  15. package/WAProto/CompanionReg/CompanionReg.d.ts +1055 -0
  16. package/WAProto/CompanionReg/CompanionReg.js +3532 -0
  17. package/WAProto/CompanionReg/CompanionReg.proto +89 -0
  18. package/WAProto/DeviceCapabilities/DeviceCapabilities.d.ts +187 -0
  19. package/WAProto/DeviceCapabilities/DeviceCapabilities.js +520 -0
  20. package/WAProto/DeviceCapabilities/DeviceCapabilities.proto +14 -0
  21. package/WAProto/E2E/E2E.d.ts +28417 -0
  22. package/WAProto/E2E/E2E.js +98438 -0
  23. package/WAProto/E2E/E2E.proto +2289 -0
  24. package/WAProto/Ephemeral/Ephemeral.d.ts +95 -0
  25. package/WAProto/Ephemeral/Ephemeral.js +269 -0
  26. package/WAProto/Ephemeral/Ephemeral.proto +6 -0
  27. package/WAProto/HistorySync/HistorySync.d.ts +40728 -0
  28. package/WAProto/HistorySync/HistorySync.js +142980 -0
  29. package/WAProto/HistorySync/HistorySync.proto +207 -0
  30. package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.d.ts +189 -0
  31. package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.js +585 -0
  32. package/WAProto/LidMigrationSyncPayload/LidMigrationSyncPayload.proto +11 -0
  33. package/WAProto/MdStorageChatRowOpaqueData/MdStorageChatRowOpaqueData.d.ts +461 -0
  34. package/WAProto/MdStorageChatRowOpaqueData/MdStorageChatRowOpaqueData.js +1559 -0
  35. package/WAProto/MdStorageChatRowOpaqueData/MdStorageChatRowOpaqueData.proto +37 -0
  36. package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.d.ts +29294 -0
  37. package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.js +101732 -0
  38. package/WAProto/MdStorageMsgRowOpaqueData/MdStorageMsgRowOpaqueData.proto +76 -0
  39. package/WAProto/MmsRetry/MmsRetry.d.ts +200 -0
  40. package/WAProto/MmsRetry/MmsRetry.js +586 -0
  41. package/WAProto/MmsRetry/MmsRetry.proto +17 -0
  42. package/WAProto/Protocol/Protocol.d.ts +218 -0
  43. package/WAProto/Protocol/Protocol.js +701 -0
  44. package/WAProto/Protocol/Protocol.proto +20 -0
  45. package/WAProto/Reporting/Reporting.d.ts +301 -0
  46. package/WAProto/Reporting/Reporting.js +989 -0
  47. package/WAProto/Reporting/Reporting.proto +19 -0
  48. package/WAProto/ServerSync/ServerSync.d.ts +1050 -0
  49. package/WAProto/ServerSync/ServerSync.js +3176 -0
  50. package/WAProto/ServerSync/ServerSync.proto +59 -0
  51. package/WAProto/SignalLocalStorageProtocol/SignalLocalStorageProtocol.d.ts +1507 -0
  52. package/WAProto/SignalLocalStorageProtocol/SignalLocalStorageProtocol.js +4756 -0
  53. package/WAProto/SignalLocalStorageProtocol/SignalLocalStorageProtocol.proto +88 -0
  54. package/WAProto/SignalWhisperTextProtocol/SignalWhisperTextProtocol.d.ts +617 -0
  55. package/WAProto/SignalWhisperTextProtocol/SignalWhisperTextProtocol.js +1940 -0
  56. package/WAProto/SignalWhisperTextProtocol/SignalWhisperTextProtocol.proto +38 -0
  57. package/WAProto/StatusAttributions/StatusAttributions.d.ts +636 -0
  58. package/WAProto/StatusAttributions/StatusAttributions.js +2037 -0
  59. package/WAProto/StatusAttributions/StatusAttributions.proto +61 -0
  60. package/WAProto/SyncAction/SyncAction.d.ts +7227 -0
  61. package/WAProto/SyncAction/SyncAction.js +22271 -0
  62. package/WAProto/SyncAction/SyncAction.proto +423 -0
  63. package/WAProto/UserPassword/UserPassword.d.ts +298 -0
  64. package/WAProto/UserPassword/UserPassword.js +898 -0
  65. package/WAProto/UserPassword/UserPassword.proto +27 -0
  66. package/WAProto/VnameCert/VnameCert.d.ts +658 -0
  67. package/WAProto/VnameCert/VnameCert.js +2225 -0
  68. package/WAProto/VnameCert/VnameCert.proto +60 -0
  69. package/WAProto/Wa6/Wa6.d.ts +1613 -0
  70. package/WAProto/Wa6/Wa6.js +6299 -0
  71. package/WAProto/Wa6/Wa6.proto +229 -0
  72. package/WAProto/Web/Web.d.ts +31718 -0
  73. package/WAProto/Web/Web.js +113402 -0
  74. package/WAProto/Web/Web.proto +545 -0
  75. package/WAProto/index.d.ts +49 -0
  76. package/WAProto/index.js +28 -0
  77. package/WASignalGroup/GroupProtocol.js +1771 -0
  78. package/WASignalGroup/ciphertext_message.js +10 -0
  79. package/WASignalGroup/group_cipher.js +103 -0
  80. package/WASignalGroup/group_session_builder.js +39 -0
  81. package/WASignalGroup/index.js +5 -0
  82. package/WASignalGroup/keyhelper.js +17 -0
  83. package/WASignalGroup/protobufs.js +2 -0
  84. package/WASignalGroup/queue_job.js +64 -0
  85. package/WASignalGroup/sender_chain_key.js +38 -0
  86. package/WASignalGroup/sender_key_distribution_message.js +68 -0
  87. package/WASignalGroup/sender_key_message.js +79 -0
  88. package/WASignalGroup/sender_key_name.js +59 -0
  89. package/WASignalGroup/sender_key_record.js +47 -0
  90. package/WASignalGroup/sender_key_state.js +110 -0
  91. package/WASignalGroup/sender_message_key.js +30 -0
  92. package/check-node-version.js +10 -0
  93. package/lib/Defaults/baileys-version.json +3 -0
  94. package/lib/Defaults/index.d.ts +51 -0
  95. package/lib/Defaults/index.js +108 -0
  96. package/lib/Defaults/phonenumber-mcc.json +223 -0
  97. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  98. package/lib/Signal/Group/ciphertext-message.js +19 -0
  99. package/lib/Signal/Group/group-session-builder.d.ts +17 -0
  100. package/lib/Signal/Group/group-session-builder.js +72 -0
  101. package/lib/Signal/Group/group_cipher.d.ts +19 -0
  102. package/lib/Signal/Group/group_cipher.js +99 -0
  103. package/lib/Signal/Group/index.d.ts +11 -0
  104. package/lib/Signal/Group/index.js +61 -0
  105. package/lib/Signal/Group/keyhelper.d.ts +16 -0
  106. package/lib/Signal/Group/keyhelper.js +66 -0
  107. package/lib/Signal/Group/queue-job.d.ts +1 -0
  108. package/lib/Signal/Group/queue-job.js +64 -0
  109. package/lib/Signal/Group/sender-chain-key.d.ts +14 -0
  110. package/lib/Signal/Group/sender-chain-key.js +39 -0
  111. package/lib/Signal/Group/sender-key-distribution-message.d.ts +17 -0
  112. package/lib/Signal/Group/sender-key-distribution-message.js +71 -0
  113. package/lib/Signal/Group/sender-key-message.d.ts +19 -0
  114. package/lib/Signal/Group/sender-key-message.js +73 -0
  115. package/lib/Signal/Group/sender-key-name.d.ts +19 -0
  116. package/lib/Signal/Group/sender-key-name.js +59 -0
  117. package/lib/Signal/Group/sender-key-record.d.ts +32 -0
  118. package/lib/Signal/Group/sender-key-record.js +53 -0
  119. package/lib/Signal/Group/sender-key-record.ts +77 -0
  120. package/lib/Signal/Group/sender-key-state.d.ts +44 -0
  121. package/lib/Signal/Group/sender-key-state.js +104 -0
  122. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  123. package/lib/Signal/Group/sender-message-key.js +33 -0
  124. package/lib/Signal/libsignal.d.ts +3 -0
  125. package/lib/Signal/libsignal.js +153 -0
  126. package/lib/Socket/Client/index.d.ts +2 -0
  127. package/lib/Socket/Client/index.js +18 -0
  128. package/lib/Socket/Client/types.d.ts +15 -0
  129. package/lib/Socket/Client/types.js +14 -0
  130. package/lib/Socket/Client/websocket.d.ts +12 -0
  131. package/lib/Socket/Client/websocket.js +57 -0
  132. package/lib/Socket/business.d.ts +181 -0
  133. package/lib/Socket/business.js +259 -0
  134. package/lib/Socket/chats.d.ts +95 -0
  135. package/lib/Socket/chats.js +906 -0
  136. package/lib/Socket/community.d.ts +131 -0
  137. package/lib/Socket/community.js +369 -0
  138. package/lib/Socket/groups.d.ts +122 -0
  139. package/lib/Socket/groups.js +360 -0
  140. package/lib/Socket/index.d.ts +183 -0
  141. package/lib/Socket/index.js +10 -0
  142. package/lib/Socket/messages-recv.d.ts +170 -0
  143. package/lib/Socket/messages-recv.js +1074 -0
  144. package/lib/Socket/messages-send.d.ts +161 -0
  145. package/lib/Socket/messages-send.js +982 -0
  146. package/lib/Socket/newsletter.d.ts +140 -0
  147. package/lib/Socket/newsletter.js +242 -0
  148. package/lib/Socket/socket.d.ts +43 -0
  149. package/lib/Socket/socket.js +749 -0
  150. package/lib/Socket/usync.d.ts +36 -0
  151. package/lib/Socket/usync.js +71 -0
  152. package/lib/Store/index.d.ts +4 -0
  153. package/lib/Store/index.js +20 -0
  154. package/lib/Store/make-cache-manager-store.d.ts +13 -0
  155. package/lib/Store/make-cache-manager-store.js +77 -0
  156. package/lib/Store/make-in-memory-store.d.ts +117 -0
  157. package/lib/Store/make-in-memory-store.js +420 -0
  158. package/lib/Store/make-ordered-dictionary.d.ts +12 -0
  159. package/lib/Store/make-ordered-dictionary.js +83 -0
  160. package/lib/Store/object-repository.d.ts +10 -0
  161. package/lib/Store/object-repository.js +28 -0
  162. package/lib/Types/Auth.d.ts +103 -0
  163. package/lib/Types/Auth.js +2 -0
  164. package/lib/Types/Call.d.ts +13 -0
  165. package/lib/Types/Call.js +2 -0
  166. package/lib/Types/Chat.d.ts +115 -0
  167. package/lib/Types/Chat.js +6 -0
  168. package/lib/Types/Contact.d.ts +35 -0
  169. package/lib/Types/Contact.js +2 -0
  170. package/lib/Types/Events.d.ts +208 -0
  171. package/lib/Types/Events.js +2 -0
  172. package/lib/Types/GroupMetadata.d.ts +81 -0
  173. package/lib/Types/GroupMetadata.js +2 -0
  174. package/lib/Types/Label.d.ts +46 -0
  175. package/lib/Types/Label.js +28 -0
  176. package/lib/Types/LabelAssociation.d.ts +29 -0
  177. package/lib/Types/LabelAssociation.js +10 -0
  178. package/lib/Types/Message.d.ts +480 -0
  179. package/lib/Types/Message.js +9 -0
  180. package/lib/Types/MexUpdates.d.ts +9 -0
  181. package/lib/Types/MexUpdates.js +18 -0
  182. package/lib/Types/Newsletter.d.ts +92 -0
  183. package/lib/Types/Newsletter.js +33 -0
  184. package/lib/Types/Product.d.ts +78 -0
  185. package/lib/Types/Product.js +2 -0
  186. package/lib/Types/Signal.d.ts +57 -0
  187. package/lib/Types/Signal.js +2 -0
  188. package/lib/Types/Socket.d.ts +116 -0
  189. package/lib/Types/Socket.js +2 -0
  190. package/lib/Types/State.d.ts +27 -0
  191. package/lib/Types/State.js +2 -0
  192. package/lib/Types/USync.d.ts +25 -0
  193. package/lib/Types/USync.js +2 -0
  194. package/lib/Types/index.d.ts +70 -0
  195. package/lib/Types/index.js +42 -0
  196. package/lib/Utils/auth-utils.d.ts +18 -0
  197. package/lib/Utils/auth-utils.js +198 -0
  198. package/lib/Utils/baileys-event-stream.d.ts +16 -0
  199. package/lib/Utils/baileys-event-stream.js +64 -0
  200. package/lib/Utils/business.d.ts +22 -0
  201. package/lib/Utils/business.js +243 -0
  202. package/lib/Utils/chat-utils.d.ts +72 -0
  203. package/lib/Utils/chat-utils.js +762 -0
  204. package/lib/Utils/crypto.d.ts +40 -0
  205. package/lib/Utils/crypto.js +150 -0
  206. package/lib/Utils/decode-wa-message.d.ts +252 -0
  207. package/lib/Utils/decode-wa-message.js +232 -0
  208. package/lib/Utils/event-buffer.d.ts +35 -0
  209. package/lib/Utils/event-buffer.js +539 -0
  210. package/lib/Utils/generics.d.ts +96 -0
  211. package/lib/Utils/generics.js +553 -0
  212. package/lib/Utils/history.d.ts +29 -0
  213. package/lib/Utils/history.js +109 -0
  214. package/lib/Utils/index.d.ts +19 -0
  215. package/lib/Utils/index.js +35 -0
  216. package/lib/Utils/link-preview.d.ts +21 -0
  217. package/lib/Utils/link-preview.js +112 -0
  218. package/lib/Utils/logger.d.ts +11 -0
  219. package/lib/Utils/logger.js +7 -0
  220. package/lib/Utils/lt-hash.d.ts +12 -0
  221. package/lib/Utils/lt-hash.js +53 -0
  222. package/lib/Utils/make-mutex.d.ts +7 -0
  223. package/lib/Utils/make-mutex.js +45 -0
  224. package/lib/Utils/messages-media.d.ts +104 -0
  225. package/lib/Utils/messages-media.js +751 -0
  226. package/lib/Utils/messages.d.ts +80 -0
  227. package/lib/Utils/messages.js +1741 -0
  228. package/lib/Utils/noise-handler.d.ts +19 -0
  229. package/lib/Utils/noise-handler.js +150 -0
  230. package/lib/Utils/process-message.d.ts +41 -0
  231. package/lib/Utils/process-message.js +391 -0
  232. package/lib/Utils/signal.d.ts +33 -0
  233. package/lib/Utils/signal.js +154 -0
  234. package/lib/Utils/use-mongo-file-auth-state.d.ts +5 -0
  235. package/lib/Utils/use-mongo-file-auth-state.js +75 -0
  236. package/lib/Utils/use-multi-file-auth-state.d.ts +12 -0
  237. package/lib/Utils/use-multi-file-auth-state.js +123 -0
  238. package/lib/Utils/use-single-file-auth-state.d.ts +12 -0
  239. package/lib/Utils/use-single-file-auth-state.js +75 -0
  240. package/lib/Utils/validate-connection.d.ts +10 -0
  241. package/lib/Utils/validate-connection.js +174 -0
  242. package/lib/WABinary/constants.d.ts +27 -0
  243. package/lib/WABinary/constants.js +45 -0
  244. package/lib/WABinary/decode.d.ts +6 -0
  245. package/lib/WABinary/decode.js +255 -0
  246. package/lib/WABinary/encode.d.ts +2 -0
  247. package/lib/WABinary/encode.js +243 -0
  248. package/lib/WABinary/generic-utils.d.ts +16 -0
  249. package/lib/WABinary/generic-utils.js +125 -0
  250. package/lib/WABinary/index.d.ts +5 -0
  251. package/lib/WABinary/index.js +21 -0
  252. package/lib/WABinary/jid-utils.d.ts +34 -0
  253. package/lib/WABinary/jid-utils.js +73 -0
  254. package/lib/WABinary/types.d.ts +18 -0
  255. package/lib/WABinary/types.js +2 -0
  256. package/lib/WAM/BinaryInfo.d.ts +16 -0
  257. package/lib/WAM/BinaryInfo.js +14 -0
  258. package/lib/WAM/constants.d.ts +39 -0
  259. package/lib/WAM/constants.js +15362 -0
  260. package/lib/WAM/encode.d.ts +2 -0
  261. package/lib/WAM/encode.js +156 -0
  262. package/lib/WAM/index.d.ts +3 -0
  263. package/lib/WAM/index.js +19 -0
  264. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.d.ts +25 -0
  265. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +60 -0
  266. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -0
  267. package/lib/WAUSync/Protocols/USyncContactProtocol.js +32 -0
  268. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
  269. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +58 -0
  270. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  271. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +31 -0
  272. package/lib/WAUSync/Protocols/USyncLIDProtocol.d.ts +8 -0
  273. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +26 -0
  274. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  275. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  276. package/lib/WAUSync/Protocols/index.d.ts +6 -0
  277. package/lib/WAUSync/Protocols/index.js +22 -0
  278. package/lib/WAUSync/USyncQuery.d.ts +28 -0
  279. package/lib/WAUSync/USyncQuery.js +88 -0
  280. package/lib/WAUSync/USyncUser.d.ts +12 -0
  281. package/lib/WAUSync/USyncUser.js +27 -0
  282. package/lib/WAUSync/index.d.ts +3 -0
  283. package/lib/WAUSync/index.js +19 -0
  284. package/lib/index.d.ts +13 -0
  285. package/lib/index.js +45 -0
  286. package/package.json +63 -0
@@ -0,0 +1,154 @@
1
+ "use strict"
2
+ Object.defineProperty(exports, "__esModule", { value: true })
3
+ const lodash_1 = require("lodash")
4
+ const Defaults_1 = require("../Defaults")
5
+ const WABinary_1 = require("../WABinary")
6
+ const crypto_1 = require("./crypto")
7
+ const generics_1 = require("./generics")
8
+ const createSignalIdentity = (wid, accountSignatureKey) => {
9
+ return {
10
+ identifier: { name: wid, deviceId: 0 },
11
+ identifierKey: crypto_1.generateSignalPubKey(accountSignatureKey)
12
+ }
13
+ }
14
+ const getPreKeys = async ({ get }, min, limit) => {
15
+ const idList = []
16
+ for (let id = min; id < limit; id++) {
17
+ idList.push(id.toString())
18
+ }
19
+ return get('pre-key', idList)
20
+ }
21
+ const generateOrGetPreKeys = (creds, range) => {
22
+ const avaliable = creds.nextPreKeyId - creds.firstUnuploadedPreKeyId
23
+ const remaining = range - avaliable
24
+ const lastPreKeyId = creds.nextPreKeyId + remaining - 1
25
+ const newPreKeys = {}
26
+ if (remaining > 0) {
27
+ for (let i = creds.nextPreKeyId; i <= lastPreKeyId; i++) {
28
+ newPreKeys[i] = crypto_1.Curve.generateKeyPair()
29
+ }
30
+ }
31
+ return {
32
+ newPreKeys,
33
+ lastPreKeyId,
34
+ preKeysRange: [creds.firstUnuploadedPreKeyId, range],
35
+ }
36
+ }
37
+ const xmppSignedPreKey = (key) => ({
38
+ tag: 'skey',
39
+ attrs: {},
40
+ content: [
41
+ { tag: 'id', attrs: {}, content: generics_1.encodeBigEndian(key.keyId, 3) },
42
+ { tag: 'value', attrs: {}, content: key.keyPair.public },
43
+ { tag: 'signature', attrs: {}, content: key.signature }
44
+ ]
45
+ })
46
+ const xmppPreKey = (pair, id) => ({
47
+ tag: 'key',
48
+ attrs: {},
49
+ content: [
50
+ { tag: 'id', attrs: {}, content: generics_1.encodeBigEndian(id, 3) },
51
+ { tag: 'value', attrs: {}, content: pair.public }
52
+ ]
53
+ })
54
+ const parseAndInjectE2ESessions = async (node, repository) => {
55
+ const extractKey = (key) => (key ? ({
56
+ keyId: WABinary_1.getBinaryNodeChildUInt(key, 'id', 3),
57
+ publicKey: crypto_1.generateSignalPubKey(WABinary_1.getBinaryNodeChildBuffer(key, 'value')),
58
+ signature: WABinary_1.getBinaryNodeChildBuffer(key, 'signature')
59
+ }) : undefined)
60
+ const nodes = WABinary_1.getBinaryNodeChildren(WABinary_1.getBinaryNodeChild(node, 'list'), 'user')
61
+ for (const node of nodes) {
62
+ WABinary_1.assertNodeErrorFree(node)
63
+ }
64
+ // Most of the work in repository.injectE2ESession is CPU intensive, not IO
65
+ // So Promise.all doesn't really help here,
66
+ // but blocks even loop if we're using it inside keys.transaction, and it makes it "sync" actually
67
+ // This way we chunk it in smaller parts and between those parts we can yield to the event loop
68
+ // It's rare case when you need to E2E sessions for so many users, but it's possible
69
+ const chunkSize = 100
70
+ const chunks = lodash_1.chunk(nodes, chunkSize)
71
+ for (const nodesChunk of chunks) {
72
+ await Promise.all(nodesChunk.map(async (node) => {
73
+ const signedKey = WABinary_1.getBinaryNodeChild(node, 'skey')
74
+ const key = WABinary_1.getBinaryNodeChild(node, 'key')
75
+ const identity = WABinary_1.getBinaryNodeChildBuffer(node, 'identity')
76
+ const jid = node.attrs.jid
77
+ const registrationId = WABinary_1.getBinaryNodeChildUInt(node, 'registration', 4)
78
+ await repository.injectE2ESession({
79
+ jid,
80
+ session: {
81
+ registrationId: registrationId,
82
+ identityKey: crypto_1.generateSignalPubKey(identity),
83
+ signedPreKey: extractKey(signedKey),
84
+ preKey: extractKey(key)
85
+ }
86
+ })
87
+ }))
88
+ }
89
+ }
90
+ const extractDeviceJids = (result, myJid, excludeZeroDevices) => {
91
+ const { user: myUser, device: myDevice } = WABinary_1.jidDecode(myJid)
92
+ const extracted = []
93
+ for (const userResult of result) {
94
+ const { devices, id } = userResult
95
+ const { user } = WABinary_1.jidDecode(id)
96
+ const deviceList = devices?.deviceList
97
+ if (Array.isArray(deviceList)) {
98
+ for (const { id: device, keyIndex } of deviceList) {
99
+ if ((!excludeZeroDevices || device !== 0) && // if zero devices are not-excluded, or device is non zero
100
+ (myUser !== user || myDevice !== device) && // either different user or if me user, not this device
101
+ (device === 0 || !!keyIndex) // ensure that "key-index" is specified for "non-zero" devices, produces a bad req otherwise
102
+ ) {
103
+ extracted.push({ user, device })
104
+ }
105
+ }
106
+ }
107
+ }
108
+ return extracted
109
+ }
110
+ /**
111
+ * get the next N keys for upload or processing
112
+ * @param count number of pre-keys to get or generate
113
+ */
114
+ const getNextPreKeys = async ({ creds, keys }, count) => {
115
+ const { newPreKeys, lastPreKeyId, preKeysRange } = generateOrGetPreKeys(creds, count)
116
+ const update = {
117
+ nextPreKeyId: Math.max(lastPreKeyId + 1, creds.nextPreKeyId),
118
+ firstUnuploadedPreKeyId: Math.max(creds.firstUnuploadedPreKeyId, lastPreKeyId + 1)
119
+ }
120
+ await keys.set({ 'pre-key': newPreKeys })
121
+ const preKeys = await getPreKeys(keys, preKeysRange[0], preKeysRange[0] + preKeysRange[1])
122
+ return { update, preKeys }
123
+ }
124
+ const getNextPreKeysNode = async (state, count) => {
125
+ const { creds } = state
126
+ const { update, preKeys } = await getNextPreKeys(state, count)
127
+ const node = {
128
+ tag: 'iq',
129
+ attrs: {
130
+ xmlns: 'encrypt',
131
+ type: 'set',
132
+ to: WABinary_1.S_WHATSAPP_NET,
133
+ },
134
+ content: [
135
+ { tag: 'registration', attrs: {}, content: generics_1.encodeBigEndian(creds.registrationId) },
136
+ { tag: 'type', attrs: {}, content: Defaults_1.KEY_BUNDLE_TYPE },
137
+ { tag: 'identity', attrs: {}, content: creds.signedIdentityKey.public },
138
+ { tag: 'list', attrs: {}, content: Object.keys(preKeys).map(k => xmppPreKey(preKeys[+k], +k)) },
139
+ xmppSignedPreKey(creds.signedPreKey)
140
+ ]
141
+ }
142
+ return { update, node }
143
+ }
144
+ module.exports = {
145
+ createSignalIdentity,
146
+ getPreKeys,
147
+ generateOrGetPreKeys,
148
+ xmppSignedPreKey,
149
+ xmppPreKey,
150
+ parseAndInjectE2ESessions,
151
+ extractDeviceJids,
152
+ getNextPreKeys,
153
+ getNextPreKeysNode
154
+ }
@@ -0,0 +1,5 @@
1
+ import { AuthenticationState } from '../Types'
2
+ export declare const useMongoFileAuthState: (collection: string) => Promise<{
3
+ state: AuthenticationState
4
+ saveCreds: () => Promise<void>
5
+ }>
@@ -0,0 +1,75 @@
1
+ "use strict"
2
+ Object.defineProperty(exports, "__esModule", { value: true })
3
+ const WAProto_1 = require("../../WAProto")
4
+ const auth_utils_1 = require("./auth-utils")
5
+ const generics_1 = require("./generics")
6
+ /*
7
+ code from amiruldev readjusted by @irull2nd, don't delete WM!
8
+ */
9
+ const useMongoFileAuthState = async (collection) => {
10
+ const writeData = (data,id) => {
11
+ const informationToStore = JSON.parse(
12
+ JSON.stringify(data, generics_1.BufferJSON.replacer)
13
+ )
14
+ const update = {
15
+ $set: {
16
+ ...informationToStore,
17
+ },
18
+ }
19
+ return collection.updateOne({_id: id},update, {upsert: true})
20
+ }
21
+ const readData = async (id) => {
22
+ try {
23
+ const data = JSON.stringify(await collection.findOne({_id: id}))
24
+ return JSON.parse(data, generics_1.BufferJSON.reviver)
25
+ } catch (err) {
26
+ console.log(err)
27
+ }
28
+ }
29
+ const removeData = async (id) => {
30
+ try{
31
+ await collection.deleteOne({_id: id})
32
+ }catch(err){
33
+ console.log('error',err)
34
+ }
35
+ }
36
+ const creds = (await readData('creds')) || auth_utils_1.initAuthCreds()
37
+ return{
38
+ state:{
39
+ creds,
40
+ keys: {
41
+ get: async (type,ids)=> {
42
+ const data = {}
43
+ await Promise
44
+ .all(
45
+ ids.map(async (id) => {
46
+ let value = await readData(`${type}-${id}`)
47
+ if(type === "app-state-sync-key"){
48
+ value = WAProto_1.proto.Message.AppStateSyncKeyData.fromObject(data)
49
+ }
50
+ data[id] = value
51
+ })
52
+ )
53
+ return data
54
+ },
55
+ set: async (data) => {
56
+ const tasks = []
57
+ for (const category of Object.keys(data)){
58
+ for (const id of Object.keys(data[category])){
59
+ const value = data[category][id]
60
+ const key = `${category}-${id}`
61
+ tasks.push(value? writeData(value,key) : removeData(key))
62
+ }
63
+ }
64
+ await Promise.all(tasks)
65
+ },
66
+ },
67
+ },
68
+ saveCreds: () => {
69
+ return writeData(creds, "creds")
70
+ }
71
+ }
72
+ }
73
+ module.exports = {
74
+ useMongoFileAuthState
75
+ }
@@ -0,0 +1,12 @@
1
+ import { AuthenticationState } from '../Types'
2
+ /**
3
+ * stores the full authentication state in a single folder.
4
+ * Far more efficient than singlefileauthstate
5
+ *
6
+ * Again, I wouldn't endorse this for any production level use other than perhaps a bot.
7
+ * Would recommend writing an auth state for use with a proper SQL or No-SQL DB
8
+ * */
9
+ export declare const useMultiFileAuthState: (folder: string) => Promise<{
10
+ state: AuthenticationState
11
+ saveCreds: () => Promise<void>
12
+ }>
@@ -0,0 +1,123 @@
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
+ const async_mutex_1 = __importDefault(require("async-mutex"))
7
+ const promises_1 = require("fs/promises")
8
+ const path_1 = require("path")
9
+ const WAProto_1 = require("../../WAProto")
10
+ const auth_utils_1 = require("./auth-utils")
11
+ const generics_1 = require("./generics")
12
+ // We need to lock files due to the fact that we are using async functions to read and write files
13
+ // https://github.com/WhiskeySockets/Baileys/issues/794
14
+ // https://github.com/nodejs/node/issues/26338
15
+ // Use a Map to store mutexes for each file path
16
+ const fileLocks = new Map()
17
+ // Get or create a mutex for a specific file path
18
+ const getFileLock = (path) => {
19
+ let mutex = fileLocks.get(path)
20
+ if (!mutex) {
21
+ mutex = new async_mutex_1.Mutex()
22
+ fileLocks.set(path, mutex)
23
+ }
24
+ return mutex
25
+ }
26
+ /**
27
+ * stores the full authentication state in a single folder.
28
+ * Far more efficient than singlefileauthstate
29
+ *
30
+ * Again, I wouldn't endorse this for any production level use other than perhaps a bot.
31
+ * Would recommend writing an auth state for use with a proper SQL or No-SQL DB
32
+ * */
33
+ const useMultiFileAuthState = async (folder) => {
34
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
+ const writeData = async (data, file) => {
36
+ const filePath = path_1.join(folder, fixFileName(file))
37
+ const mutex = getFileLock(filePath)
38
+ return mutex.acquire().then(async (release) => {
39
+ try {
40
+ await promises_1.writeFile(filePath, JSON.stringify(data, generics_1.BufferJSON.replacer))
41
+ } finally {
42
+ release()
43
+ }
44
+ })
45
+ }
46
+ const readData = async (file) => {
47
+ try {
48
+ const filePath = path_1.join(folder, fixFileName(file))
49
+ const mutex = getFileLock(filePath)
50
+ const data = await mutex.acquire().then(async (release) => {
51
+ try {
52
+ return await promises_1.readFile(filePath, { encoding: 'utf-8' })
53
+ } finally {
54
+ release()
55
+ }
56
+ })
57
+ return JSON.parse(data, generics_1.BufferJSON.reviver)
58
+ } catch (error) {
59
+ return null
60
+ }
61
+ }
62
+ const removeData = async (file) => {
63
+ try {
64
+ const filePath = path_1.join(folder, fixFileName(file))
65
+ const mutex = getFileLock(filePath)
66
+ await mutex.acquire().then(async (release) => {
67
+ try {
68
+ await promises_1.unlink(filePath)
69
+ } finally {
70
+ release()
71
+ }
72
+ })
73
+ } catch {}
74
+ }
75
+ const folderInfo = await promises_1.stat(folder).catch(() => { })
76
+ if (folderInfo) {
77
+ if (!folderInfo.isDirectory()) {
78
+ throw new Error(`found something that is not a directory at ${folder}, either delete it or specify a different location`)
79
+ }
80
+ }
81
+ else {
82
+ await promises_1.mkdir(folder, { recursive: true })
83
+ }
84
+ const fixFileName = (file) => {
85
+ return file?.replace(/\//g, '__')?.replace(/:/g, '-')
86
+ }
87
+ const creds = await readData('creds.json') || auth_utils_1.initAuthCreds()
88
+ return {
89
+ state: {
90
+ creds,
91
+ keys: {
92
+ get: async (type, ids) => {
93
+ const data = {}
94
+ await Promise.all(ids.map(async (id) => {
95
+ let value = await readData(`${type}-${id}.json`)
96
+ if (type === 'app-state-sync-key' && value) {
97
+ value = WAProto_1.proto.Message.AppStateSyncKeyData.fromObject(value)
98
+ }
99
+ data[id] = value
100
+ }))
101
+ return data
102
+ },
103
+ set: async (data) => {
104
+ const tasks = []
105
+ for (const category in data) {
106
+ for (const id in data[category]) {
107
+ const value = data[category][id]
108
+ const file = `${category}-${id}.json`
109
+ tasks.push(value ? writeData(value, file) : removeData(file))
110
+ }
111
+ }
112
+ await Promise.all(tasks)
113
+ }
114
+ }
115
+ },
116
+ saveCreds: async () => {
117
+ return writeData(creds, 'creds.json')
118
+ }
119
+ }
120
+ }
121
+ module.exports = {
122
+ useMultiFileAuthState
123
+ }
@@ -0,0 +1,12 @@
1
+ import { ILogger } from './logger'
2
+ import type { AuthenticationState } from '../Types'
3
+ /**
4
+ * @deprecated use multi file auth state instead please
5
+ * stores the full authentication state in a single JSON file
6
+ *
7
+ * DO NOT USE IN A PROD ENVIRONMENT, only meant to serve as an example
8
+ * */
9
+ export declare const useSingleFileAuthState: (filename: string, logger?: ILogger) => {
10
+ state: AuthenticationState
11
+ saveState: () => void
12
+ }
@@ -0,0 +1,75 @@
1
+ "use strict"
2
+ Object.defineProperty(exports, "__esModule", { value: true })
3
+ const WAProto_1 = require("../../WAProto")
4
+ const auth_utils_1 = require("./auth-utils")
5
+ const generics_1 = require("./generics")
6
+ // useless key map only there to maintain backwards compatibility
7
+ // do not use in your own systems please
8
+ const KEY_MAP = {
9
+ 'pre-key': 'preKeys',
10
+ 'session': 'sessions',
11
+ 'sender-key': 'senderKeys',
12
+ 'app-state-sync-key': 'appStateSyncKeys',
13
+ 'app-state-sync-version': 'appStateVersions',
14
+ 'sender-key-memory': 'senderKeyMemory'
15
+ }
16
+ /**
17
+ * @deprecated use multi file auth state instead please
18
+ * stores the full authentication state in a single JSON file
19
+ *
20
+ * DO NOT USE IN A PROD ENVIRONMENT, only meant to serve as an example
21
+ * */
22
+ const useSingleFileAuthState = (filename, logger) => {
23
+ // require fs here so that in case "fs" is not available -- the app does not crash
24
+ const { readFileSync, writeFileSync, existsSync } = require('fs')
25
+ let creds
26
+ let keys = {}
27
+ // save the authentication state to a file
28
+ const saveState = () => {
29
+ logger && logger.trace('saving auth state')
30
+ writeFileSync(filename,
31
+ // BufferJSON replacer utility saves buffers nicely
32
+ JSON.stringify({ creds, keys }, generics_1.BufferJSON.replacer, 2))
33
+ }
34
+ if (existsSync(filename)) {
35
+ const result = JSON.parse(readFileSync(filename, { encoding: 'utf-8' }), generics_1.BufferJSON.reviver)
36
+ creds = result.creds
37
+ keys = result.keys
38
+ }
39
+ else {
40
+ creds = auth_utils_1.initAuthCreds()
41
+ keys = {}
42
+ }
43
+ return {
44
+ state: {
45
+ creds,
46
+ keys: {
47
+ get: (type, ids) => {
48
+ const key = KEY_MAP[type]
49
+ return ids.reduce((dict, id) => {
50
+ let value = keys[key]?.[id]
51
+ if (value) {
52
+ if (type === 'app-state-sync-key') {
53
+ value = WAProto_1.proto.Message.AppStateSyncKeyData.fromObject(value)
54
+ }
55
+ dict[id] = value
56
+ }
57
+ return dict
58
+ }, {})
59
+ },
60
+ set: (data) => {
61
+ for (const _key in data) {
62
+ const key = KEY_MAP[_key]
63
+ keys[key] = keys[key] || {}
64
+ Object.assign(keys[key], data[_key])
65
+ }
66
+ saveState()
67
+ }
68
+ }
69
+ },
70
+ saveState
71
+ }
72
+ }
73
+ module.exports = {
74
+ useSingleFileAuthState
75
+ }
@@ -0,0 +1,10 @@
1
+ import { proto } from '../../WAProto'
2
+ import type { AuthenticationCreds, SignalCreds, SocketConfig } from '../Types'
3
+ import { BinaryNode } from '../WABinary'
4
+ export declare const generateLoginNode: (userJid: string, config: SocketConfig) => proto.IClientPayload
5
+ export declare const generateRegistrationNode: ({ registrationId, signedPreKey, signedIdentityKey }: SignalCreds, config: SocketConfig) => proto.ClientPayload
6
+ export declare const configureSuccessfulPairing: (stanza: BinaryNode, { advSecretKey, signedIdentityKey, signalIdentities }: Pick<AuthenticationCreds, 'advSecretKey' | 'signedIdentityKey' | 'signalIdentities'>) => {
7
+ creds: Partial<AuthenticationCreds>
8
+ reply: BinaryNode
9
+ }
10
+ export declare const encodeSignedDeviceIdentity: (account: proto.IADVSignedDeviceIdentity, includeSignatureKey: boolean) => Uint8Array
@@ -0,0 +1,174 @@
1
+ "use strict"
2
+ Object.defineProperty(exports, "__esModule", { value: true })
3
+ const boom_1 = require("@hapi/boom")
4
+ const crypto_1 = require("crypto")
5
+ const WAProto_1 = require("../../WAProto")
6
+ const Defaults_1 = require("../Defaults")
7
+ const WABinary_1 = require("../WABinary")
8
+ const crypto_2 = require("./crypto")
9
+ const generics_1 = require("./generics")
10
+ const signal_1 = require("./signal")
11
+ const getUserAgent = (config) => {
12
+ return {
13
+ appVersion: {
14
+ primary: config.version[0],
15
+ secondary: config.version[1],
16
+ tertiary: config.version[2],
17
+ },
18
+ platform: WAProto_1.proto.ClientPayload.UserAgent.Platform.WEB,
19
+ releaseChannel: WAProto_1.proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
20
+ osVersion: '0.1',
21
+ device: 'Desktop',
22
+ osBuildNumber: '0.1',
23
+ localeLanguageIso6391: 'en',
24
+ mnc: '000',
25
+ mcc: '000',
26
+ localeCountryIso31661Alpha2: config.countryCode,
27
+ }
28
+ }
29
+ const PLATFORM_MAP = {
30
+ 'Mac OS': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.DARWIN,
31
+ 'Windows': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN32,
32
+ 'Android': WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WIN_HYBRID
33
+ }
34
+ const getWebInfo = (config) => {
35
+ let webSubPlatform = WAProto_1.proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER
36
+ if (config.syncFullHistory && PLATFORM_MAP[config.browser[0]]) {
37
+ webSubPlatform = PLATFORM_MAP[config.browser[0]]
38
+ }
39
+ return { webSubPlatform }
40
+ }
41
+ const getClientPayload = (config) => {
42
+ const payload = {
43
+ connectType: WAProto_1.proto.ClientPayload.ConnectType.WIFI_UNKNOWN,
44
+ connectReason: WAProto_1.proto.ClientPayload.ConnectReason.USER_ACTIVATED,
45
+ userAgent: getUserAgent(config),
46
+ }
47
+ payload.webInfo = getWebInfo(config)
48
+ return payload
49
+ }
50
+ const generateLoginNode = (userJid, config) => {
51
+ const { user, device } = WABinary_1.jidDecode(userJid)
52
+ const payload = {
53
+ ...getClientPayload(config),
54
+ passive: false,
55
+ pull: true,
56
+ username: +user,
57
+ device: device,
58
+ }
59
+ return WAProto_1.proto.ClientPayload.fromObject(payload)
60
+ }
61
+ const getPlatformType = (platform) => {
62
+ const platformType = platform.toUpperCase()
63
+ return WAProto_1.proto.DeviceProps.PlatformType[platformType] || WAProto_1.proto.DeviceProps.PlatformType.DESKTOP
64
+ }
65
+ const generateRegistrationNode = ({ registrationId, signedPreKey, signedIdentityKey }, config) => {
66
+ // the app version needs to be md5 hashed
67
+ // and passed in
68
+ const appVersionBuf = crypto_1.createHash('md5')
69
+ .update(config.version.join('.')) // join as string
70
+ .digest()
71
+ const companion = {
72
+ os: config.browser[0],
73
+ platformType: getPlatformType(config.browser[1]),
74
+ requireFullSync: config.syncFullHistory,
75
+ }
76
+ const companionProto = WAProto_1.proto.DeviceProps.encode(companion).finish()
77
+ const registerPayload = {
78
+ ...getClientPayload(config),
79
+ passive: false,
80
+ pull: false,
81
+ devicePairingData: {
82
+ buildHash: appVersionBuf,
83
+ deviceProps: companionProto,
84
+ eRegid: generics_1.encodeBigEndian(registrationId),
85
+ eKeytype: Defaults_1.KEY_BUNDLE_TYPE,
86
+ eIdent: signedIdentityKey.public,
87
+ eSkeyId: generics_1.encodeBigEndian(signedPreKey.keyId, 3),
88
+ eSkeyVal: signedPreKey.keyPair.public,
89
+ eSkeySig: signedPreKey.signature,
90
+ },
91
+ }
92
+ return WAProto_1.proto.ClientPayload.fromObject(registerPayload)
93
+ }
94
+ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, signalIdentities }) => {
95
+ const msgId = stanza.attrs.id
96
+ const pairSuccessNode = WABinary_1.getBinaryNodeChild(stanza, 'pair-success')
97
+ const deviceIdentityNode = WABinary_1.getBinaryNodeChild(pairSuccessNode, 'device-identity')
98
+ const platformNode = WABinary_1.getBinaryNodeChild(pairSuccessNode, 'platform')
99
+ const deviceNode = WABinary_1.getBinaryNodeChild(pairSuccessNode, 'device')
100
+ const businessNode = WABinary_1.getBinaryNodeChild(pairSuccessNode, 'biz')
101
+ if (!deviceIdentityNode || !deviceNode) {
102
+ throw new boom_1.Boom('Missing device-identity or device in pair success node', { data: stanza })
103
+ }
104
+ const bizName = businessNode?.attrs?.name
105
+ const jid = deviceNode.attrs.jid
106
+ const { details, hmac } = WAProto_1.proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content)
107
+ // check HMAC matches
108
+ const advSign = crypto_2.hmacSign(details, Buffer.from(advSecretKey, 'base64'))
109
+ if (Buffer.compare(hmac, advSign) !== 0) {
110
+ throw new boom_1.Boom('Invalid account signature')
111
+ }
112
+ const account = WAProto_1.proto.ADVSignedDeviceIdentity.decode(details)
113
+ const { accountSignatureKey, accountSignature, details: deviceDetails } = account
114
+ // verify the device signature matches
115
+ const accountMsg = Buffer.concat([Buffer.from([6, 0]), deviceDetails, signedIdentityKey.public])
116
+ if (!crypto_2.Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
117
+ throw new boom_1.Boom('Failed to verify account signature')
118
+ }
119
+ // sign the details with our identity key
120
+ const deviceMsg = Buffer.concat([Buffer.from([6, 1]), deviceDetails, signedIdentityKey.public, accountSignatureKey])
121
+ account.deviceSignature = crypto_2.Curve.sign(signedIdentityKey.private, deviceMsg)
122
+ const identity = signal_1.createSignalIdentity(jid, accountSignatureKey)
123
+ const accountEnc = encodeSignedDeviceIdentity(account, false)
124
+ const deviceIdentity = WAProto_1.proto.ADVDeviceIdentity.decode(account.details)
125
+ const reply = {
126
+ tag: 'iq',
127
+ attrs: {
128
+ to: WABinary_1.S_WHATSAPP_NET,
129
+ type: 'result',
130
+ id: msgId,
131
+ },
132
+ content: [
133
+ {
134
+ tag: 'pair-device-sign',
135
+ attrs: {},
136
+ content: [
137
+ {
138
+ tag: 'device-identity',
139
+ attrs: { 'key-index': deviceIdentity.keyIndex.toString() },
140
+ content: accountEnc
141
+ }
142
+ ]
143
+ }
144
+ ]
145
+ }
146
+ const authUpdate = {
147
+ account,
148
+ me: { id: jid, name: bizName },
149
+ signalIdentities: [
150
+ ...(signalIdentities || []),
151
+ identity
152
+ ],
153
+ platform: platformNode?.attrs?.name
154
+ }
155
+ return {
156
+ creds: authUpdate,
157
+ reply
158
+ }
159
+ }
160
+ const encodeSignedDeviceIdentity = (account, includeSignatureKey) => {
161
+ account = { ...account }
162
+ // set to null if we are not to include the signature key
163
+ // or if we are including the signature key but it is empty
164
+ if (!includeSignatureKey || !account.accountSignatureKey?.length) {
165
+ account.accountSignatureKey = null
166
+ }
167
+ return WAProto_1.proto.ADVSignedDeviceIdentity.encode(account).finish()
168
+ }
169
+ module.exports = {
170
+ generateLoginNode,
171
+ generateRegistrationNode,
172
+ configureSuccessfulPairing,
173
+ encodeSignedDeviceIdentity
174
+ }
@@ -0,0 +1,27 @@
1
+ export declare const TAGS: {
2
+ LIST_EMPTY: number
3
+ DICTIONARY_0: number
4
+ DICTIONARY_1: number
5
+ DICTIONARY_2: number
6
+ DICTIONARY_3: number
7
+ AD_JID: number
8
+ LIST_8: number
9
+ LIST_16: number
10
+ JID_PAIR: number
11
+ HEX_8: number
12
+ BINARY_8: number
13
+ BINARY_20: number
14
+ BINARY_32: number
15
+ NIBBLE_8: number
16
+ PACKED_MAX: number
17
+ SINGLE_BYTE_MAX: number
18
+ STREAM_END: number
19
+ }
20
+ export declare const DOUBLE_BYTE_TOKENS: string[][]
21
+ export declare const SINGLE_BYTE_TOKENS: (string | null)[]
22
+ export declare const TOKEN_MAP: {
23
+ [token: string]: {
24
+ dict?: number
25
+ index: number
26
+ }
27
+ }