kersiosocket 0.0.0-stage → 0.5.0-dev

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 (55) hide show
  1. package/BUILD-INFO.md +14 -0
  2. package/CHANGELOG.md +19 -0
  3. package/LICENSE +21 -0
  4. package/README.md +145 -2
  5. package/bench/wabinary.js +31 -0
  6. package/docs/PROTOCOL-ROADMAP.md +43 -0
  7. package/docs/RESEARCH-BASELINE.md +25 -0
  8. package/docs/WABINARY.md +37 -0
  9. package/examples/basic.js +18 -0
  10. package/examples/client-payload.js +21 -0
  11. package/examples/device-props.js +18 -0
  12. package/examples/sessions.js +11 -0
  13. package/examples/wabinary.js +15 -0
  14. package/licenses/THIRD-PARTY-NOTICES.md +7 -0
  15. package/licenses/whatsmeow-MPL-2.0.txt +374 -0
  16. package/package.json +36 -3
  17. package/scripts/import-token-table.js +95 -0
  18. package/src/index.js +25 -0
  19. package/src/pairing/adapter.js +115 -0
  20. package/src/pairing/lifecycle.js +120 -0
  21. package/src/pairing/qr.js +38 -0
  22. package/src/proto/client-payload.js +185 -0
  23. package/src/proto/device-props.js +143 -0
  24. package/src/proto/handshake.js +79 -0
  25. package/src/proto/wire.js +137 -0
  26. package/src/protocol/node-protocol.js +155 -0
  27. package/src/session/codec.js +25 -0
  28. package/src/session/encrypted-store.js +107 -0
  29. package/src/session/manager.js +61 -0
  30. package/src/session/stores.js +154 -0
  31. package/src/socket/connection.js +265 -0
  32. package/src/socket/frame.js +77 -0
  33. package/src/socket/make.js +70 -0
  34. package/src/socket/noise.js +126 -0
  35. package/src/socket/transport.js +39 -0
  36. package/src/utils/crypto.js +52 -0
  37. package/src/utils/latency.js +32 -0
  38. package/src/utils/lru.js +76 -0
  39. package/src/wabinary/codec.js +374 -0
  40. package/src/wabinary/tags.js +25 -0
  41. package/src/wabinary/token-source.js +146 -0
  42. package/src/wabinary/tokens.json +1287 -0
  43. package/test/connection.test.js +153 -0
  44. package/test/device-props.test.js +67 -0
  45. package/test/encrypted-store.test.js +54 -0
  46. package/test/frame.test.js +37 -0
  47. package/test/helpers.js +43 -0
  48. package/test/node-protocol.test.js +90 -0
  49. package/test/noise.test.js +66 -0
  50. package/test/pairing-adapter.test.js +71 -0
  51. package/test/pairing.test.js +32 -0
  52. package/test/proto.test.js +64 -0
  53. package/test/session.test.js +134 -0
  54. package/test/token-source.test.js +35 -0
  55. package/test/wabinary.test.js +147 -0
package/BUILD-INFO.md ADDED
@@ -0,0 +1,14 @@
1
+ # Build information — KersioSocket v0.5.0-dev
2
+
3
+ - Package version: `0.5.0-dev`
4
+ - Verification runtime: Node.js `v22.16.0`
5
+ - Test suite: `60/60` passing with `npm test`
6
+ - Serial test suite: `60/60` passing with `npm run test:serial`
7
+ - Syntax checks: core WABinary, NodeProtocol, DeviceProps, and pairing adapter passed
8
+ - Examples checked: `examples/wabinary.js`, `examples/device-props.js`, `examples/client-payload.js`
9
+ - Token data inside this archive: intentionally empty placeholder
10
+ - Refresh token data after extraction: `npm run refresh:tokens`
11
+
12
+ ## Evidence boundary
13
+
14
+ The tests establish local behavior only. They do not establish successful live WhatsApp authentication, current server compatibility, Noise server-certificate verification, signed pairing-success validation, Pairing Code flow, Signal Protocol interoperability, or `sendMessage` functionality. See `docs/RESEARCH-BASELINE.md` and `docs/PROTOCOL-ROADMAP.md`.
package/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Changelog
2
+
3
+ ## 0.5.0-dev — major protocol foundations upgrade
4
+
5
+ - WABinary defaults to the `0x00` uncompressed prefix; adds explicit golden-byte test, optional zlib `0x02` prefix, packed digit/hex strings, AD-JID and decode fixtures for FB/INTEROP JIDs, plus bounded parser checks.
6
+ - Adds `NodeProtocol` for inbound node events and outbound IQ queries, pending request limits, timeout, cancellation, remote IQ errors, and connection-close cleanup. A non-empty dictionary is required unless a caller explicitly enables an empty table for tests.
7
+ - Adds `DeviceProps` / `HistorySyncConfig` encoders and a builder for registration fields from caller-provided keys/signature. The helper never generates or verifies cryptographic material.
8
+ - Connects an early QR adapter to the node event surface, sends the observed IQ acknowledgement, and emits QR candidates. It deliberately does not mark a `pair-success` stanza verified.
9
+ - Adds `EncryptedStore` using AES-256-GCM with AAD bound to the key, and clear no-plaintext-fallback behavior.
10
+ - Adds a local WABinary performance baseline, source snapshot inventory and refreshed roadmap.
11
+ - Improves listener isolation and reconnect/error regression tests.
12
+
13
+ ## Existing foundations retained
14
+
15
+ Noise XX transport loopback, framing, atomic file store, SQLite and fake-client Redis/Mongo adapters, session manager, LRU, and token-source importer remain in place.
16
+
17
+ ## Important status
18
+
19
+ This is still development code. The server Noise certificate chain is not verified, full pairing-success signatures/HMAC are not verified, pairing code is not implemented, Signal Protocol is not implemented, and no live WhatsApp login/send-message capability is claimed.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 KersioSocket contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,146 @@
1
- # Temporary Holding Version
1
+ # KersioSocket
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Library protokol WhatsApp Web eksperimental yang ditulis sebagai proyek mandiri. Target desainnya adalah API event yang mudah dipakai, session store yang bisa diganti, isolasi multi-session, dan jalur data berbasis `Buffer` dengan batas input eksplisit.
4
+
5
+ > **Status v0.5.0-dev: belum siap dipakai login WhatsApp secara live.** Tes lokal menguji format dan state internal. Kode ini belum memverifikasi rantai sertifikat Noise server, belum memiliki implementasi Signal Protocol, dan belum memverifikasi signature/HMAC `pair-success`. Karena itu, handshake Noise atau event QR bukan bukti akun berhasil tertaut.
6
+
7
+ ## Upgrade v0.5.0-dev
8
+
9
+ - WABinary: prefix standar `0x00`, prefix zlib `0x02`, single/double token dictionary, raw UTF-8, binary values, packed nibble/hex, JID pair dan AD-JID, validasi panjang/kedalaman, serta fixture byte eksplisit.
10
+ - Protobuf: encoder manual untuk subset `ClientPayload` berdasarkan schema snapshot yang tercatat, termasuk field opsional yang sebelumnya belum ada.
11
+ - `DeviceProps`: encoder schema eksplisit, builder `createDevicePairingData()` dari kunci dan signed prekey **yang disediakan pemanggil**, ID big-endian, dan build hash MD5 dari versi aplikasi bertitik.
12
+ - `NodeProtocol`: decoding node dari frame Noise, event `node`, `node:<tag>`, `iq`, `query()` dengan timeout/abort, penanganan error remote dan pembatas IQ pending.
13
+ - QR adapter: menanggapi node `iq/pair-device` yang sudah di-decode, ack sesuai referensi, dan memancarkan kandidat payload QR dari `ref` yang diterima server. Adapter ini **tidak** mengesahkan `pair-success` atau menyimpan akun sebagai paired.
14
+ - `EncryptedStore`: AES-256-GCM dengan IV acak, AAD terikat ke storage key, serta fail-closed jika kunci salah atau envelope dimodifikasi.
15
+ - Koneksi: listener error terisolasi, kegagalan frame protokol fail-closed, dan metrik secara eksplisit melaporkan `serverCertificateVerified: false` sampai verifier sertifikat diterapkan.
16
+ - Benchmark lokal WABinary dan dokumentasi baseline riset/versi.
17
+
18
+ ## Fitur dan batasannya
19
+
20
+ | Bagian | Status di v0.5.0-dev |
21
+ |---|---|
22
+ | WebSocket, frame length prefix, reconnect backoff | Ada; koneksi target live belum diverifikasi menyeluruh |
23
+ | Noise XX, X25519, AES-GCM | Lulus tes loopback; **verifikasi sertifikat server belum ada** |
24
+ | WABinary encode/decode dan token version pin | Ada; fixture/golden test lokal. Token table tidak dibundel penuh dan perlu diimpor |
25
+ | Node layer / IQ query | Ada; diuji dengan transport tiruan, belum seluruh alur server live |
26
+ | `ClientPayload` / `DeviceProps` protobuf | Encoder schema snapshot dan fixture; bukan jaminan server menerima payload |
27
+ | QR adapter dari `pair-device` | Ada sebagai adapter awal; butuh kredensial asli yang dibuat secara benar |
28
+ | Verifikasi cryptographic `pair-success` dan simpan auth final | **Belum ada** |
29
+ | Pairing code / PBKDF2 + AES-CTR end-to-end | **Belum ada** |
30
+ | Signal Protocol, prekey upload, message encryption | **Belum ada** |
31
+ | `messages.upsert`, `sendMessage`, media, group/app-state sync | **Belum ada** |
32
+ | Store memory/file/SQLite/Redis/Mongo, LRU, multi-session | Ada; Redis/Mongo diuji dengan fake client, perlu integrasi server sungguhan |
33
+ | Store AES-GCM untuk kredensial | Ada; kunci master harus dipasok dari secret manager/environment |
34
+
35
+ ## Setup di CMD Windows
36
+
37
+ Ekstrak ZIP ke folder proyek, lalu di CMD:
38
+
39
+ ```bat
40
+ cd /d C:\kersiosocket
41
+ npm install
42
+ npm test
43
+ ```
44
+
45
+ `ws` dipakai oleh adapter WebSocket dan merupakan peer dependency opsional:
46
+
47
+ ```bat
48
+ npm install ws
49
+ ```
50
+
51
+ ### Impor token table
52
+
53
+ ZIP sengaja menyertakan `src/wabinary/tokens.json` kosong. Untuk penggunaan NodeProtocol yang membaca traffic tokenized, jalankan importer yang mengambil data dari commit publik terpin dan memvalidasi source blob SHA-1 serta lisensi:
54
+
55
+ ```bat
56
+ npm run refresh:tokens
57
+ ```
58
+
59
+ Importer memerlukan internet dari mesinmu. Hasilnya adalah dataset reverse-engineering publik, bukan tabel resmi WhatsApp dan bukan jaminan kompatibilitas versi server aktif. Simpan `licenses/whatsmeow-MPL-2.0.txt` dan `licenses/THIRD-PARTY-NOTICES.md` saat mendistribusikan hasil impor.
60
+
61
+ ## API singkat
62
+
63
+ ### Codec WABinary lokal
64
+
65
+ ```js
66
+ const { encodeBinaryNode, decodeBinaryNode, loadTokenTable } = require('./src')
67
+ const tokens = loadTokenTable()
68
+ const node = { tag: 'iq', attrs: { id: 'fixture-1', type: 'get' }, content: [{ tag: 'ping', attrs: {} }] }
69
+ const bytes = encodeBinaryNode(node, { tokens }) // sudah menyertakan prefix 0x00
70
+ const decoded = decodeBinaryNode(bytes, { tokens, requirePrefix: true })
71
+ console.log(bytes.toString('hex'), decoded)
72
+ ```
73
+
74
+ ### Socket + NodeProtocol
75
+
76
+ Gunakan setelah token table sudah diimpor. Contoh ini membangun lapisan API, bukan berarti login aktif tersedia:
77
+
78
+ ```js
79
+ const { makeSocket, loadTokenTable } = require('./src')
80
+ const sock = makeSocket({
81
+ sessionId: 'fixture-session',
82
+ clientPayload: Buffer.alloc(0), // smoke-test transport saja; bukan payload login
83
+ nodeProtocol: { tokens: loadTokenTable() }
84
+ })
85
+
86
+ sock.ev.on('connection.update', (update) => console.log(update.connection))
87
+ sock.ev.on('node', (node) => console.log('node diterima:', node.tag))
88
+ sock.ev.on('protocol.error', (error) => console.error(error.message))
89
+ // sock.query({ tag: 'iq', attrs: { type: 'get', to: 's.whatsapp.net' }, content: [...] })
90
+ ```
91
+
92
+ Untuk NodeProtocol, jangan kirim query sesuka hati ke server live; panggil query hanya ketika koneksi dan sesi autentikasi memang sudah siap. `clientPayload: Buffer.alloc(0)` di atas sengaja menandakan smoke-test transport, bukan login.
93
+
94
+ ### DeviceProps dan registration bundle
95
+
96
+ ```js
97
+ const { encodeDeviceProps, createDevicePairingData, encodeClientPayload } = require('./src')
98
+ const deviceProps = encodeDeviceProps({
99
+ os: 'Windows', version: [10, 15, 7], platformType: 'CHROME', requireFullSync: true,
100
+ historySyncConfig: { storageQuotaMb: 10240, inlineInitialPayloadInE2EeMsg: true }
101
+ })
102
+
103
+ // identityPublicKey, signedPreKey.publicKey dan signedPreKey.signature harus berasal
104
+ // dari implementasi kriptografi yang benar; helper ini TIDAK membuat atau memvalidasinya.
105
+ const pairingData = createDevicePairingData({
106
+ registrationId: existingRegistrationId,
107
+ identityPublicKey: existingIdentityPublicKey,
108
+ signedPreKey: { keyId: existingSignedPreKeyId, publicKey: existingSignedPreKeyPublic, signature: existingValidSignature },
109
+ appVersion: [2, 3000, 1043857760],
110
+ deviceProps
111
+ })
112
+
113
+ const bytes = encodeClientPayload({ mode: 'registration', userAgent, webInfo, devicePairingData: pairingData })
114
+ ```
115
+
116
+ Nama `existing...` di atas adalah placeholder penjelas dan harus diganti oleh caller; contoh tersebut sengaja bukan file yang langsung bisa dijalankan. **Jangan** mengisi signature dengan data acak: ukuran yang benar tidak berarti signature sah. Proyek ini belum membuat signed prekey, belum memverifikasi cert chain Noise, dan belum menyelesaikan verifikasi pairing.
117
+
118
+ ### Multi-session + encrypted store
119
+
120
+ ```js
121
+ const { createSessionManager, FileStore, EncryptedStore } = require('./src')
122
+ const masterKey = Buffer.from(process.env.KERSIO_STORE_KEY_HEX || '', 'hex')
123
+ if (masterKey.length !== 32) throw new Error('KERSIO_STORE_KEY_HEX harus 64 digit hex (32 byte) dari secret manager')
124
+ const store = new EncryptedStore(new FileStore('./sessions'), masterKey)
125
+ const sessions = createSessionManager({ store, autoConnect: false })
126
+ const a = sessions.open('akun-a')
127
+ const b = sessions.open('akun-b')
128
+ console.log(await sessions.list(), sessions.stats())
129
+ // Shutdown: await sessions.closeAll()
130
+ ```
131
+
132
+ Jangan taruh master key di source code. `EncryptedStore` mengenkripsi values, tetapi perlindungan backup, akses folder, kunci master, dan koordinasi multi-proses tetap tanggung jawab deployment. Jangan jalankan dua proses terhadap akun/session yang sama tanpa lock terdistribusi.
133
+
134
+ ## Tes dan benchmark
135
+
136
+ ```bat
137
+ npm test
138
+ npm run test:serial
139
+ npm run bench:wabinary
140
+ ```
141
+
142
+ Benchmark menggunakan codec KersioSocket sendiri, warm-up dan sample tetap. Angka ops/s hanya baseline mesin lokal, bukan pembuktian bahwa KersioSocket lebih cepat daripada Go, Baileys, atau zapo-js. Uji di mesin idle, catat versi Node dan status token table jika membandingkan run.
143
+
144
+ ## Referensi riset
145
+
146
+ Lihat [`docs/RESEARCH-BASELINE.md`](docs/RESEARCH-BASELINE.md) untuk file referensi, blob hash, versi schema, hasil yang dapat disimpulkan, dan batas bukti. Lihat [`docs/PROTOCOL-ROADMAP.md`](docs/PROTOCOL-ROADMAP.md) untuk gate selanjutnya.
@@ -0,0 +1,31 @@
1
+ 'use strict'
2
+
3
+ const { performance } = require('node:perf_hooks')
4
+ const { encodeBinaryNode, decodeBinaryNode, loadTokenTable } = require('../src/wabinary/codec')
5
+
6
+ const iterations = Number.parseInt(process.env.KERSIO_BENCH_ITERATIONS || '25000', 10)
7
+ if (!Number.isSafeInteger(iterations) || iterations < 100 || iterations > 2_000_000) {
8
+ throw new RangeError('KERSIO_BENCH_ITERATIONS harus 100..2000000')
9
+ }
10
+ const tokens = loadTokenTable()
11
+ const node = {
12
+ tag: 'iq',
13
+ attrs: { id: 'kersiosocket-benchmark-0001', type: 'get', to: 's.whatsapp.net', xmlns: 'w:p' },
14
+ content: [{ tag: 'ping', attrs: { t: '1234567890' } }]
15
+ }
16
+ const bytes = encodeBinaryNode(node, { tokens })
17
+ for (let i = 0; i < Math.min(2000, iterations); i++) {
18
+ encodeBinaryNode(node, { tokens })
19
+ decodeBinaryNode(bytes, { tokens, requirePrefix: true })
20
+ }
21
+ function measure(label, fn) {
22
+ const start = performance.now()
23
+ for (let i = 0; i < iterations; i++) fn()
24
+ const elapsedMs = performance.now() - start
25
+ console.log(`${label}: ${Math.round(iterations / (elapsedMs / 1000)).toLocaleString()} ops/s (${elapsedMs.toFixed(1)} ms, ${iterations} ops)`)
26
+ }
27
+ console.log('KersioSocket WABinary local benchmark')
28
+ console.log(`Node ${process.version}; iterations=${iterations}; sampleBytes=${bytes.length}; DictVersion=${tokens._metadata?.dictVersion ?? 'custom/empty'}`)
29
+ console.log('Warm-up applied. Run on an otherwise idle machine; this is not a comparison against Go/Baileys.')
30
+ measure('encode', () => { encodeBinaryNode(node, { tokens }) })
31
+ measure('decode', () => { decodeBinaryNode(bytes, { tokens, requirePrefix: true }) })
@@ -0,0 +1,43 @@
1
+ # Protocol roadmap — KersioSocket v0.5.0-dev
2
+
3
+ ## Layer saat ini
4
+
5
+ ```text
6
+ WebSocket transport + reconnect
7
+ └─ raw 3-byte length framing
8
+ └─ Noise XX + encrypted transport (server certificate verification: NOT IMPLEMENTED)
9
+ └─ ClientPayload protobuf encoder + DeviceProps helper
10
+ └─ WABinary node codec + versioned token data
11
+ └─ NodeProtocol events / pending IQ query
12
+ └─ early QR adapter (pair-device refs; no success verification)
13
+ └─ credential persistence / authenticated pairing [NEXT GATE]
14
+ └─ Signal Protocol + prekeys [NOT IMPLEMENTED]
15
+ └─ messages / media / groups / app-state [NOT IMPLEMENTED]
16
+ ```
17
+
18
+ ## v0.5.0-dev implemented and locally tested
19
+
20
+ - WABinary standard prefix and compression prefix, single/double dictionary indexes, packed nibble/hex, JID pair/AD-JID encode/decode, bounded parse and explicit fixture bytes.
21
+ - Node-level event dispatch and IQ request tracking with timeout, AbortSignal cancellation, result/error response handling, max-pending cap, connection-close cleanup.
22
+ - DeviceProps/HistorySyncConfig encoders and construction of ClientPayload registration data from caller-supplied values. `createDevicePairingData()` does not generate or validate key/signature data.
23
+ - Early QR adapter acknowledges `iq/pair-device`, formats QR payload candidates from server `ref` values, and refuses to label `pair-success` as verified.
24
+ - AES-256-GCM encrypted store wrapper with 12-byte random IV, 16-byte auth tag, AAD binding to storage key, no plaintext fallback.
25
+ - Listener-error isolation, protocol fail-closed path, tests and local benchmark.
26
+
27
+ ## Blocking gates before a live account attempt
28
+
29
+ 1. Implement and independently test Noise certificate-chain verification against the correct root/issuer and schema. Today stats explicitly report `serverCertificateVerified: false`.
30
+ 2. Obtain byte-level interoperability fixtures for a pinned Web build from an independent encoder/decoder. Current WABinary golden fixtures verify a limited sample, not all server-generated node variants.
31
+ 3. Build proper auth credentials: separate Noise static key, Signal identity key, registration ID, signed prekey and verifiable signature. Use only crypto primitives and encodings whose behavior is independently tested.
32
+ 4. Verify the complete `pair-success` chain: decode device identity; validate ADV HMAC, account signature and required fields; produce the `pair-device-sign` reply; persist updated auth credentials atomically; only then transition lifecycle to paired.
33
+ 5. Implement pairing-code flow with test vectors for PBKDF2 parameters, IV handling, AES-CTR, framing and exact wire node layout. No pairing-code event is claimed by this version.
34
+ 6. Implement Signal Protocol, prekey upload, session state, incoming/outgoing message crypto, retry receipts, then event APIs such as `messages.upsert` and `sendMessage`.
35
+ 7. Run integration tests against live Redis/Mongo (if used) and multi-session soak tests; quantify RAM and latency with repeatable benchmarks.
36
+
37
+ ## Security notes
38
+
39
+ - Noise static/ephemeral keys and Signal identity/signed-prekey keys have separate roles.
40
+ - Correct protobuf field lengths do not make a cryptographic signature valid.
41
+ - Receiving `pair-success` is not sufficient to mark paired.
42
+ - Session encryption depends on user-managed master key storage/rotation; a lost key means stored session values cannot be decrypted.
43
+ - Public reverse-engineering material is not an official stable specification; record commits/blob hashes and revalidate when targeting another server build.
@@ -0,0 +1,25 @@
1
+ # Protocol research baseline
2
+
3
+ Snapshot prepared for KersioSocket v0.5.0-dev. These references are useful for understanding observed wire behavior, not official support contracts. The Git blob hashes below identify the specific retrieved file contents; branch URLs can move later.
4
+
5
+ | Topic | Reference file | Retrieved Git blob SHA / revision | How used |
6
+ |---|---|---|---|
7
+ | WABinary encoder | [Baileys `src/WABinary/encode.ts`](https://github.com/WhiskeySockets/Baileys/blob/master/src/WABinary/encode.ts) | `c883e6ed21d1fd5d54619b9427435f1eb6166941` | Standard prefix, list/string encoding, packed strings, JID encoding decisions |
8
+ | WABinary decoder | [Baileys `src/WABinary/decode.ts`](https://github.com/WhiskeySockets/Baileys/blob/master/src/WABinary/decode.ts) | `b0183d858c2d42dfc24feb1a00108d649f87df89` | Prefix handling, packed-length semantics, JID token variants |
9
+ | WAProto schema | [Baileys `WAProto/WAProto.proto`](https://github.com/WhiskeySockets/Baileys/blob/master/WAProto/WAProto.proto) | `d76317480be18c2f7576efc8e86b8608a3b655ca` | Snapshot field numbers/enums for ClientPayload, UserAgent, WebInfo, DeviceProps, HistorySyncConfig |
10
+ | Connection defaults | [Baileys `src/Defaults/index.ts`](https://github.com/WhiskeySockets/Baileys/blob/master/src/Defaults/index.ts) | `b4c7810087194d39e311e4f38702befb2c779258` | Observed dictionary version/header convention and connection config concepts |
11
+ | QR/pair-success | [Baileys `src/Utils/validate-connection.ts`](https://github.com/WhiskeySockets/Baileys/blob/master/src/Utils/validate-connection.ts) | `9bfc5d6891e16dd37881606f5e5300b301b7e646` | Ref-based QR flow, registration fields, `DeviceProps`, HMAC/signature verification path |
12
+ | Token data | [whatsmeow `binary/token/token.go`](https://github.com/tulir/whatsmeow/blob/b2b1e71d45e2ff171153b025b5a42f475bb30ef8/binary/token/token.go) | commit `b2b1e71d45e2ff171153b025b5a42f475bb30ef8`; Git blob SHA-1 `361acd19d93c8dea30f516e27ce8c77fdaecc56f`; `DictVersion=3` | Version-pinned third-party token data imported by script; MPL-2.0 notice retained |
13
+
14
+ ## Facts established by the referenced source snapshots
15
+
16
+ - Baileys WABinary encoder initializes its output with one byte `0x00`; the decoder recognizes an uncompressed prefix and a compressed prefix. KersioSocket now has a pinned golden fixture for a small `iq/get/ping` node, not a complete conformance suite.
17
+ - `NIBBLE_8` and `HEX_8` store the count of packed bytes in the low seven bits and use the high bit to indicate odd character count. KersioSocket tests odd-length packed values.
18
+ - `DeviceProps` snapshot fields are `os=1`, `version=2`, `platformType=3`, `requireFullSync=4`, `historySyncConfig=5`; HistorySyncConfig field numbers are recorded in `src/proto/device-props.js`.
19
+ - In the inspected registration code, `eRegid` is encoded big-endian, `eKeytype` is `[5]`, `eIdent` is an identity public key, `eSkeyId` is 3-byte big-endian, `eSkeyVal` is a signed-prekey public key, `eSkeySig` is the pre-existing signature, `buildHash` is MD5 of dotted version text, and `deviceProps` is protobuf bytes.
20
+ - Pairing success handling validates HMAC/signatures and returns a `pair-device-sign` reply in the inspected source; KersioSocket has not implemented that verifier/reply and does not mark `pair-success` as completed.
21
+ - The token table is from a public reverse-engineering repository under MPL-2.0, not from an official WhatsApp-issued schema. Importer validation checks exact upstream blob hash, dictionary version and table dimensions; it does not independently validate against a live server.
22
+
23
+ ## Not claimed
24
+
25
+ No successful live WhatsApp login/pair was observed in this build. No live WebSocket interoperability, Noise server certificate verification, Signal session crypto, or `sendMessage` is claimed. Node.js unit tests and local round-trips are only local evidence.
@@ -0,0 +1,37 @@
1
+ # KersioSocket WABinary codec — v0.5.0-dev
2
+
3
+ ## Shape data
4
+
5
+ Node yang didukung:
6
+
7
+ ```js
8
+ { tag: 'iq', attrs: { id: 'fixture-1', type: 'get' }, content: [ { tag: 'ping', attrs: {} } ] }
9
+ ```
10
+
11
+ `encodeBinaryNode()` mengeluarkan `0x00` + node tanpa kompresi secara default. Dengan `{ compress: true }`, ia mengeluarkan `0x02` + zlib-deflate body. `decodeBinaryNode()` membaca prefix itu secara default; `requirePrefix: true` menolak data yang tidak diawali prefix dikenal. `withPrefix: false` hanya tersedia untuk fixture/alat lokal, bukan untuk `sock.sendNode()`.
12
+
13
+ Codec mendukung list `LIST_EMPTY/8/16`, raw UTF-8 `BINARY_8/20/32`, empat halaman dictionary double-byte, single-byte tokens, binary node content, packed `NIBBLE_8` dan `HEX_8`, JID pair dan AD-JID, serta decode FB-JID/INTEROP-JID berdasarkan bentuk referensi yang dipelajari. Penulisan FB-JID/INTEROP-JID khusus belum diimplementasikan; nilai JID tersebut dapat jatuh kembali ke JID_PAIR biasa. Validasi membatasi byte input/output, kedalaman, node count, index token, list, dan data terpotong.
14
+
15
+ ## Token dictionary
16
+
17
+ `src/wabinary/tokens.json` sengaja dikemas kosong pada ZIP; jalankan `npm run refresh:tokens`. Importer menggunakan sumber `tulir/whatsmeow/binary/token/token.go` pada commit `b2b1e71d45e2ff171153b025b5a42f475bb30ef8`, memastikan Git blob SHA-1 `361acd19d93c8dea30f516e27ce8c77fdaecc56f`, `DictVersion=3`, 236 entri single-byte dan empat page berisi 256 entri. Data itu memiliki atribusi/lisensi MPL-2.0 tersendiri; lihat `licenses/THIRD-PARTY-NOTICES.md`.
18
+
19
+ Parser token table memverifikasi dimensi dan versi bila metadata importer ada. Ini memvalidasi asal dan bentuk data, **bukan** keaktifan tabel terhadap WhatsApp server tertentu. Jangan ubah nomor token dengan perkiraan.
20
+
21
+ ## Fixtures dan bukti
22
+
23
+ `test/wabinary.test.js` berisi byte fixture eksplisit untuk node ping dengan token indeks yang tercatat pada data v3, tes binary string, JID device, kompresi, malformed input, serta round-trip. Golden fixture menguji format pada sample khusus itu; belum mewakili semua node yang dikeluarkan server. Tes live/interoperability independen masih harus dilakukan.
24
+
25
+ ## Cara terhubung ke socket
26
+
27
+ `NodeProtocol` mendengarkan plaintext frame setelah decrypt Noise dan memanggil `decodeBinaryNode`. Jika decode gagal, defaultnya fail-closed: ia mengeluarkan `protocol.error` dan menutup koneksi. `sendNode()` meng-encode prefix standar dan mengirimnya melalui Noise transport. `query()` mengelola IQ pending berdasarkan ID, timer timeout, AbortSignal, dan error balasan.
28
+
29
+ NodeProtocol memerlukan dictionary nonkosong ketika menggunakan tabel default. Untuk smoke tests internal, boleh memasok token table fixture secara eksplisit. Jangan gunakan empty table untuk menganggap decoder siap menangani server tokenized.
30
+
31
+ ## Batas yang diketahui
32
+
33
+ - Prefix/codec dan token table sudah diuji lokal, belum dibandingkan dengan server aktif.
34
+ - Decoder tidak mengimplementasikan semua variasi node/JID yang pernah diamati.
35
+ - Decoder ini mengharapkan satu node WABinary per plaintext frame; stream framing di lapisan sebelumnya yang menentukan batas frame.
36
+ - Kompresi hanya didukung melalui bentuk prefix dan zlib yang diuji; tidak berarti semua variasi kompresi server didukung.
37
+ - `NodeProtocol` bukan message layer: belum ada Signal session, message stanza transforms, upload media atau receipts.
@@ -0,0 +1,18 @@
1
+ 'use strict'
2
+ const { makeSocket } = require('../src')
3
+
4
+ // Smoke test transport/Noise only. No valid login or registration ClientPayload
5
+ // is present here, so a live WhatsApp server may close the socket after Noise.
6
+ console.warn('[demo] transport/Noise smoke test only; this example does not log in or pair an account.')
7
+
8
+ const sock = makeSocket({
9
+ logger: console,
10
+ reconnect: { enabled: false }
11
+ })
12
+
13
+ sock.ev.on('connection.update', (u) => {
14
+ console.log('update:', u.connection, u.code ?? '')
15
+ if (u.connection === 'noise-ready') console.log('Noise handshake OK. Stats:', sock.stats())
16
+ })
17
+ sock.ev.on('connection.error', (e) => console.error('error:', e.message))
18
+ sock.ev.on('frame', (f) => console.log('frame', f.length, 'byte'))
@@ -0,0 +1,21 @@
1
+ 'use strict'
2
+ // Local encoding smoke test only. These values are synthetic, not valid credentials.
3
+ const { encodeClientPayload } = require('../src')
4
+
5
+ const bytes = encodeClientPayload({
6
+ mode: 'login',
7
+ username: '6281234567890',
8
+ passive: false,
9
+ pushName: 'Kersio local test',
10
+ userAgent: {
11
+ platform: 'WEB',
12
+ appVersion: [2, 3000, 1040000000],
13
+ localeLanguage: 'id',
14
+ localeCountry: 'ID'
15
+ },
16
+ webInfo: { version: 'test-version-only', webSubPlatform: 'WEB_BROWSER' },
17
+ connectType: 'WIFI_UNKNOWN',
18
+ connectReason: 'USER_ACTIVATED'
19
+ })
20
+
21
+ console.log({ bytes: bytes.length, hexPrefix: bytes.subarray(0, 16).toString('hex') })
@@ -0,0 +1,18 @@
1
+ 'use strict'
2
+ const { encodeDeviceProps, buildAppVersionHash } = require('../src')
3
+
4
+ // Local schema example only. It creates protobuf bytes, not account credentials.
5
+ const appVersion = [2, 3000, 1043857760]
6
+ const deviceProps = encodeDeviceProps({
7
+ os: 'Windows',
8
+ version: [10, 15, 7],
9
+ platformType: 'CHROME',
10
+ requireFullSync: true,
11
+ historySyncConfig: {
12
+ storageQuotaMb: 10240,
13
+ inlineInitialPayloadInE2EeMsg: true,
14
+ supportCagReactionsAndPolls: true
15
+ }
16
+ })
17
+ console.log({ devicePropsBytes: deviceProps.length, devicePropsHex: deviceProps.toString('hex'), appVersionHash: buildAppVersionHash(appVersion).toString('hex') })
18
+ console.log('Fixture only: no private key, signed prekey signature, pairing, or live login is generated.')
@@ -0,0 +1,11 @@
1
+ 'use strict'
2
+ const { createSessionManager, FileStore } = require('../src')
3
+
4
+ const sessions = createSessionManager({ store: new FileStore('./sessions'), logger: console })
5
+ for (const id of ['nomor-a', 'nomor-b']) {
6
+ const sock = sessions.open(id)
7
+ sock.ev.on('connection.update', (u) => console.log(id, u.connection))
8
+ sock.ev.on('connection.error', (e) => console.error(id, e.message))
9
+ }
10
+ setInterval(() => console.log(JSON.stringify(sessions.stats())), 10000)
11
+ process.on('SIGINT', async () => { await sessions.closeAll(); process.exit(0) })
@@ -0,0 +1,15 @@
1
+ 'use strict'
2
+
3
+ const { encodeBinaryNode, decodeBinaryNode, loadTokenTable } = require('../src')
4
+
5
+ // This demonstrates the codec with the project's intentionally empty token table.
6
+ // It validates local structure/round-trip only; it is NOT a live WhatsApp fixture.
7
+ const tokens = loadTokenTable()
8
+ const sample = {
9
+ tag: 'iq',
10
+ attrs: { id: 'kersio-local-test', type: 'get', to: 's.whatsapp.net' },
11
+ content: [{ tag: 'ping', attrs: {} }]
12
+ }
13
+ const bytes = encodeBinaryNode(sample, { tokens })
14
+ const decoded = decodeBinaryNode(bytes, { tokens })
15
+ console.log({ bytes: bytes.length, hex: bytes.toString('hex'), decoded })
@@ -0,0 +1,7 @@
1
+ # Third-party notices
2
+
3
+ KersioSocket implementation source is distributed under the MIT license stated in `package.json` and `LICENSE`.
4
+
5
+ When `npm run refresh:tokens` is executed, the importer retrieves token **data** from [`tulir/whatsmeow`](https://github.com/tulir/whatsmeow/blob/b2b1e71d45e2ff171153b025b5a42f475bb30ef8/binary/token/token.go), commit `b2b1e71d45e2ff171153b025b5a42f475bb30ef8`, source blob SHA-1 `361acd19d93c8dea30f516e27ce8c77fdaecc56f`. That token data is identified by the upstream project as MPL-2.0. The importer saves the source license at `licenses/whatsmeow-MPL-2.0.txt` and embeds the source metadata in `src/wabinary/tokens.json`.
6
+
7
+ Keep the generated metadata and license if redistributing an imported token table. The token table is reverse-engineered third-party data, not an official WhatsApp-issued table or a guarantee of current server compatibility. KersioSocket protocol/codec code is implemented separately; refer to `docs/RESEARCH-BASELINE.md` for researched source snapshots.