kersiosocket 0.0.0-stage → 0.6.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.
- package/BUILD-INFO.md +15 -0
- package/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +191 -2
- package/bench/wabinary.js +31 -0
- package/bridges/whatsmeow/README.md +42 -0
- package/docs/ENGINE-MATRIX.md +23 -0
- package/docs/PROTOCOL-ROADMAP.md +74 -0
- package/docs/RESEARCH-BASELINE.md +36 -0
- package/docs/WABINARY.md +37 -0
- package/examples/basic.js +10 -0
- package/examples/client-payload.js +21 -0
- package/examples/device-props.js +18 -0
- package/examples/sessions.js +11 -0
- package/examples/wabinary.js +15 -0
- package/licenses/THIRD-PARTY-NOTICES.md +12 -0
- package/package.json +31 -4
- package/scripts/import-token-table.js +95 -0
- package/src/backends/baileys.js +121 -0
- package/src/backends/base.js +102 -0
- package/src/backends/whatsmeow-process.js +202 -0
- package/src/backends/zapo.js +123 -0
- package/src/client/kersio-client.js +305 -0
- package/src/client/session-manager.js +67 -0
- package/src/index.js +36 -0
- package/src/pairing/adapter.js +115 -0
- package/src/pairing/lifecycle.js +120 -0
- package/src/pairing/qr.js +38 -0
- package/src/pairing/verified-commit.js +46 -0
- package/src/proto/client-payload.js +185 -0
- package/src/proto/device-props.js +143 -0
- package/src/proto/handshake.js +79 -0
- package/src/proto/wire.js +137 -0
- package/src/protocol/node-protocol.js +155 -0
- package/src/session/codec.js +25 -0
- package/src/session/encrypted-store.js +107 -0
- package/src/session/locking.js +233 -0
- package/src/session/manager.js +61 -0
- package/src/session/stores.js +154 -0
- package/src/socket/connection.js +278 -0
- package/src/socket/frame.js +77 -0
- package/src/socket/make.js +70 -0
- package/src/socket/noise.js +146 -0
- package/src/socket/transport.js +39 -0
- package/src/utils/crypto.js +52 -0
- package/src/utils/latency.js +32 -0
- package/src/utils/lru.js +76 -0
- package/src/wabinary/codec.js +374 -0
- package/src/wabinary/tags.js +25 -0
- package/src/wabinary/token-source.js +146 -0
- package/src/wabinary/tokens.json +5 -0
- package/test/backend-adapters.test.js +59 -0
- package/test/connection.test.js +173 -0
- package/test/device-props.test.js +67 -0
- package/test/encrypted-store.test.js +54 -0
- package/test/frame.test.js +37 -0
- package/test/helpers.js +43 -0
- package/test/locking-archive.test.js +49 -0
- package/test/node-protocol.test.js +90 -0
- package/test/noise.test.js +88 -0
- package/test/pairing-adapter.test.js +71 -0
- package/test/pairing.test.js +32 -0
- package/test/proto.test.js +64 -0
- package/test/session-manager.test.js +34 -0
- package/test/session.test.js +134 -0
- package/test/token-source.test.js +35 -0
- package/test/unified-client.test.js +63 -0
- package/test/verified-commit.test.js +43 -0
- package/test/wabinary.test.js +147 -0
- package/test/whatsmeow-process.test.js +43 -0
package/BUILD-INFO.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Build information — KersioSocket v0.6.0-dev
|
|
2
|
+
|
|
3
|
+
- Package version: `0.6.0-dev`
|
|
4
|
+
- Verification runtime: Node.js `v22.16.0`
|
|
5
|
+
- Full automated suite: `78/78` passing with `npm test`
|
|
6
|
+
- Serial suite: `78/78` passing with `npm run test:serial`
|
|
7
|
+
- Backend/facade bridge suite: `9/9` passing with `npm run test:backends`
|
|
8
|
+
- JavaScript syntax: `node --check` passed for every project `.js` file outside `node_modules`
|
|
9
|
+
- Packaging: `npm pack --dry-run` completed; 70 package files listed
|
|
10
|
+
- Token data inside this archive: intentionally empty placeholder
|
|
11
|
+
- Refresh token data after extraction: `npm run refresh:tokens`
|
|
12
|
+
|
|
13
|
+
## Evidence boundary
|
|
14
|
+
|
|
15
|
+
The tests establish local behavior and adapter contracts only. They do not establish successful live WhatsApp authentication, server trust/pinning, cryptographic verification of a real WhatsApp pairing-success response, Pairing Code end-to-end, Signal Protocol interoperability, actual live media/group/app-state support, or performance relative to Baileys, Zapo-JS, or whatsmeow. The native engine still fails closed when no server-certificate verifier is configured and does not yet implement a complete native Signal/message engine. Baileys and Zapo-JS features are delegated through adapters; whatsmeow is an external JSONL sidecar contract and its Go binary is not included. See `README.md`, `docs/ENGINE-MATRIX.md`, `docs/RESEARCH-BASELINE.md`, and `docs/PROTOCOL-ROADMAP.md`.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.6.0-dev — unified engine facade and hardening
|
|
4
|
+
|
|
5
|
+
- Adds `KersioClient` / `createKersioClient()` with normalized connection, pairing, message, credential, and history events plus explicit capability errors.
|
|
6
|
+
- Adds adapters for an existing `zapo-js` `WaClient`, an `@whiskeysockets/baileys` socket/factory, and a bounded JSONL-RPC Go `whatsmeow` process bridge.
|
|
7
|
+
- Adds normalized high-level message builders for text, media, location, contacts, polls, reactions, edit and delete. The selected engine remains the implementation of transport/protocol semantics; backend coverage varies.
|
|
8
|
+
- Adds `KersioSessionManager` so distinct accounts may select distinct engines in one process.
|
|
9
|
+
- Adds `MessageArchive` (bounded per-chat history + `getMessage()`), `KeyedMutex`, local-filesystem `FileLockManager`, and `LockedStore`.
|
|
10
|
+
- Makes native `Connection` fail closed by default if no Noise server-certificate verifier is configured; adds optional synchronous verifier hook and verified-pairing commit guard.
|
|
11
|
+
- Documents that the Go sidecar is a separate executable and the bridge test is transport-only; does not ship or claim an untested Go protocol implementation.
|
|
12
|
+
- Adds mocked adapter/bridge, archive/lock, secure-pairing and strict-Noise tests. No live WhatsApp account test is claimed.
|
|
13
|
+
|
|
14
|
+
## 0.5.0-dev — major protocol foundations upgrade
|
|
15
|
+
|
|
16
|
+
- 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.
|
|
17
|
+
- 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.
|
|
18
|
+
- Adds `DeviceProps` / `HistorySyncConfig` encoders and a builder for registration fields from caller-provided keys/signature. The helper never generates or verifies cryptographic material.
|
|
19
|
+
- 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.
|
|
20
|
+
- Adds `EncryptedStore` using AES-256-GCM with AAD bound to the key, and clear no-plaintext-fallback behavior.
|
|
21
|
+
- Adds a local WABinary performance baseline, source snapshot inventory and refreshed roadmap.
|
|
22
|
+
- Improves listener isolation and reconnect/error regression tests.
|
|
23
|
+
|
|
24
|
+
## Existing foundations retained
|
|
25
|
+
|
|
26
|
+
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.
|
|
27
|
+
|
|
28
|
+
## Important status
|
|
29
|
+
|
|
30
|
+
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,192 @@
|
|
|
1
|
-
#
|
|
1
|
+
# KersioSocket v0.6.0-dev
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
KersioSocket v0.6 adds a **common API facade** for three independently maintained WhatsApp Web client engines: `zapo-js`, `@whiskeysockets/baileys`, and a Go `whatsmeow` process bridge. It keeps the original KersioSocket native transport/protocol research code and adds message helpers, event normalization, selectable multi-session engines, message archive, and file-based locking.
|
|
4
|
+
|
|
5
|
+
> **Honest status:** this is a development build. The Zapo and Baileys adapters are tested with mocked clients, and the Go bridge transport is tested with a mock JSONL process; there is no live-account integration test in this ZIP. The Go `whatsmeow` executable is **not bundled**. The native KersioSocket engine remains experimental: by default it fails closed when Noise server-certificate verification is not configured, and this package does not include a verified WhatsApp certificate-root chain, a full native Signal Protocol implementation, or an internal cryptographic verifier for pairing-success. Choose a maintained backend for live messaging rather than disabling security checks.
|
|
6
|
+
|
|
7
|
+
## Apa arti “digabung” di v0.6?
|
|
8
|
+
|
|
9
|
+
KersioSocket menyatukan API dan lifecycle backend di satu package, bukan mencampur tiga set auth key/Signal session menjadi satu sesi protokol. Untuk setiap akun WhatsApp, pilih **satu** engine pemilik transport, autentikasi, dan state. Beberapa akun boleh menggunakan engine berbeda di satu proses melalui `KersioSessionManager`. Menjalankan Baileys, Zapo, dan whatsmeow bersamaan dengan kredensial akun yang sama tidak disarankan karena ketiganya mengelola sesi dan counter protokol sendiri.
|
|
10
|
+
|
|
11
|
+
Engine:
|
|
12
|
+
|
|
13
|
+
- **Zapo-JS** — adapter ke API `WaClient` dan `.message.send()`; sesi, Signal, prekey, media, dan app-state dikelola Zapo. Konfigurasi store diberikan oleh pemanggil agar KersioSocket tidak menebak backend/credential provider.
|
|
14
|
+
- **Baileys** — adapter ke socket Baileys; meneruskan event, QR/pairing code, credential updates, pesan, media download bila modul helper tersedia, dan method socket yang diizinkan.
|
|
15
|
+
- **Go whatsmeow process** — JSON Lines RPC bridge terbatasi ke executable Go yang dibuat terpisah. Lihat `bridges/whatsmeow/README.md` untuk protokolnya. Hasil mock test bukan bukti bahwa binary Go atau koneksi WhatsApp live sudah diuji.
|
|
16
|
+
- **Native KersioSocket** — tetap menyediakan codec WABinary, Noise framing, IQ/node protocol, dan adapter pairing awal; fitur autentikasi dan enkripsi pesan native belum lengkap untuk sesi live.
|
|
17
|
+
|
|
18
|
+
## Install dan tests
|
|
19
|
+
|
|
20
|
+
Butuh Node.js **22.5 atau lebih baru**. Engine eksternal bersifat opsional supaya pemasangan core tidak memaksa dua client tambahan.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install
|
|
24
|
+
npm test
|
|
25
|
+
npm run test:serial
|
|
26
|
+
npm run test:backends
|
|
27
|
+
npm run bench:wabinary
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Instal engine yang memang ingin dipakai:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install zapo-js
|
|
34
|
+
# atau
|
|
35
|
+
npm install @whiskeysockets/baileys
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Untuk Zapo dengan SQLite gunakan paket add-on yang didokumentasikan Zapo, misalnya `@zapo-js/store-sqlite` bersama driver `better-sqlite3`. Ikuti persyaratan OS/runtime driver dan dokumentasi upstream. Library ini tidak memasang/mengonfigurasi database server secara otomatis.
|
|
39
|
+
|
|
40
|
+
## API umum
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
const { createKersioClient } = require('kersiosocket')
|
|
44
|
+
|
|
45
|
+
// zapoClient adalah instance WaClient zapo-js yang sudah kamu konfigurasi dan kelola
|
|
46
|
+
const zapoClient = createYourConfiguredZapoClient()
|
|
47
|
+
const client = await createKersioClient({ engine: 'zapo', client: zapoClient, sessionId: 'akun-1' })
|
|
48
|
+
client.on('pairing.qr', ({ qr }) => console.log('QR:', qr))
|
|
49
|
+
client.on('pairing.code', ({ code }) => console.log('Pairing code:', code))
|
|
50
|
+
client.on('messages.upsert', async ({ messages }) => {
|
|
51
|
+
for (const message of messages) console.log(message.key?.remoteJid, message.message)
|
|
52
|
+
})
|
|
53
|
+
client.on('connection.update', (update) => console.log('connection:', update.connection))
|
|
54
|
+
client.on('backend.error', ({ error }) => console.error(error))
|
|
55
|
+
|
|
56
|
+
await client.connect()
|
|
57
|
+
// Kirim hanya sesudah backend memberi status connection.update open.
|
|
58
|
+
await client.sendText('6281234567890@s.whatsapp.net', 'Halo dari KersioSocket')
|
|
59
|
+
await client.close()
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Ganti `createYourConfiguredZapoClient()` dengan inisialisasi `WaClient` milikmu, seperti contoh lengkap pada bagian Zapo-JS di bawah.
|
|
63
|
+
|
|
64
|
+
### Zapo-JS
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
const { createKersioClient } = require('./src')
|
|
68
|
+
const { createStore, WaClient, ConsoleLogger } = require('zapo-js')
|
|
69
|
+
const { createSqliteStore } = require('@zapo-js/store-sqlite')
|
|
70
|
+
|
|
71
|
+
const store = createStore({
|
|
72
|
+
backends: { sqlite: createSqliteStore({ path: '.auth/state.sqlite' }) },
|
|
73
|
+
providers: {
|
|
74
|
+
auth: 'sqlite', signal: 'sqlite', preKey: 'sqlite', session: 'sqlite',
|
|
75
|
+
identity: 'sqlite', senderKey: 'sqlite', appState: 'sqlite', privacyToken: 'sqlite',
|
|
76
|
+
messages: 'sqlite', threads: 'sqlite', contacts: 'sqlite'
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
const zapoClient = new WaClient({ store, sessionId: 'akun-1' }, new ConsoleLogger('info'))
|
|
80
|
+
const client = await createKersioClient({ engine: 'zapo', client: zapoClient, sessionId: 'akun-1' })
|
|
81
|
+
client.on('pairing.qr', ({ qr }) => console.log(qr))
|
|
82
|
+
client.on('messages.upsert', ({ messages }) => console.log(messages.length, 'pesan'))
|
|
83
|
+
await client.connect()
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
KersioSocket tidak otomatis menyimpan credentials Zapo sendiri. Store milik Zapo harus menyimpan provider `auth`, `signal`, `preKey`, `session`, `identity`, `senderKey`, dan `appState` sebagaimana dibutuhkan engine. Pertahankan dokumentasi dan versi Zapo yang dipakai.
|
|
87
|
+
|
|
88
|
+
### Baileys
|
|
89
|
+
|
|
90
|
+
```js
|
|
91
|
+
const baileys = await import('@whiskeysockets/baileys')
|
|
92
|
+
const { state, saveCreds } = await baileys.useMultiFileAuthState('./auth-baileys')
|
|
93
|
+
const client = await require('./src').createKersioClient({
|
|
94
|
+
engine: 'baileys',
|
|
95
|
+
socketOptions: { auth: state, printQRInTerminal: false },
|
|
96
|
+
baileysModule: baileys
|
|
97
|
+
})
|
|
98
|
+
client.on('creds.update', saveCreds)
|
|
99
|
+
client.on('pairing.qr', ({ qr }) => console.log(qr))
|
|
100
|
+
client.on('messages.upsert', ({ messages }) => console.log(messages.length))
|
|
101
|
+
await client.connect()
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Untuk penggunaan serius, ikuti panduan upstream tentang penyimpanan credentials/Signal keys dan dampak perubahan versi API Baileys. `useMultiFileAuthState` ditujukan sebagai contoh/kemudahan; rancang storage persisten yang tepat untuk production.
|
|
105
|
+
|
|
106
|
+
### Go `whatsmeow`
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
const { createKersioClient } = require('./src')
|
|
110
|
+
const client = await createKersioClient({
|
|
111
|
+
engine: 'whatsmeow',
|
|
112
|
+
sessionId: 'akun-go',
|
|
113
|
+
bridge: { command: './whatsmeow-bridge', args: [] }
|
|
114
|
+
})
|
|
115
|
+
client.on('messages.upsert', ({ messages }) => console.log(messages))
|
|
116
|
+
await client.connect()
|
|
117
|
+
await client.sendText('6281234567890@s.whatsapp.net', 'Halo dari bridge Go')
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`./whatsmeow-bridge` harus executable sidecar yang implementasi JSONL RPC-nya mengikuti `bridges/whatsmeow/README.md`; binary tersebut tidak ada di ZIP ini. KersioSocket tidak mengklaim API Go live sampai sidecar yang dipilih terbangun dan diuji sendiri.
|
|
121
|
+
|
|
122
|
+
## API pesan terpadu
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
await client.sendMessage(jid, { text: 'Halo' })
|
|
126
|
+
await client.sendText(jid, 'Halo')
|
|
127
|
+
await client.sendImage(jid, Buffer.from(imageBytes), { caption: 'Foto' })
|
|
128
|
+
await client.sendVideo(jid, Buffer.from(videoBytes), { caption: 'Video' })
|
|
129
|
+
await client.sendAudio(jid, Buffer.from(audioBytes), { mimetype: 'audio/ogg' })
|
|
130
|
+
await client.sendDocument(jid, Buffer.from(fileBytes), { fileName: 'contoh.pdf', mimetype: 'application/pdf' })
|
|
131
|
+
await client.sendSticker(jid, Buffer.from(webpBytes))
|
|
132
|
+
await client.sendLocation(jid, { latitude: -6.2, longitude: 106.8, name: 'Jakarta' })
|
|
133
|
+
await client.sendContact(jid, { displayName: 'Nama', vcard: 'BEGIN:VCARD\\nVERSION:3.0\\nFN:Nama\\nEND:VCARD' })
|
|
134
|
+
await client.sendPoll(jid, { name: 'Pilih', values: ['A', 'B'], selectableCount: 1 })
|
|
135
|
+
await client.react(jid, messageKey, '👍')
|
|
136
|
+
await client.editMessage(jid, messageKey, 'Teks baru')
|
|
137
|
+
await client.deleteMessage(jid, messageKey)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
These are normalized content objects passed to the selected engine. Not every backend/version supports every payload. Feature-specific operations fail explicitly when no implementation is exposed; KersioSocket does not claim that constructing an object proves server support. Group/app-state methods can be accessed through `client.invoke(...)`, using the method/path documented by the chosen backend. Avoid invoking untrusted method names from user input.
|
|
141
|
+
|
|
142
|
+
## Multi-session
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
const { createKersioSessionManager } = require('./src')
|
|
146
|
+
const manager = createKersioSessionManager()
|
|
147
|
+
const a = await manager.open('akun-zapo', { engine: 'zapo', client: zapoClient })
|
|
148
|
+
const b = await manager.open('akun-baileys', { engine: 'baileys', socketOptions: { auth: baileysAuth } })
|
|
149
|
+
console.log(manager.stats())
|
|
150
|
+
await manager.close('akun-zapo')
|
|
151
|
+
await manager.closeAll()
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
This manager prevents duplicate session IDs within one process. It is not a substitute for a distributed scheduler or lock when several processes share one auth database.
|
|
155
|
+
|
|
156
|
+
## Storage dan stabilitas
|
|
157
|
+
|
|
158
|
+
- Existing `MemoryStore`, `FileStore`, `SQLiteStore`, `RedisStore`, `MongoStore`, and `EncryptedStore` are retained.
|
|
159
|
+
- `MessageArchive` stores per-chat message history up to a configurable limit and exposes `getMessage(key)` for retry/reply retrieval.
|
|
160
|
+
- `FileLockManager` provides cooperative local-filesystem lock leases; `LockedStore` wraps operations under those locks. Do not treat this as a distributed lock for network filesystems.
|
|
161
|
+
- Existing Redis/Mongo adapter tests use fake clients. Set up real services and integration-test them before production.
|
|
162
|
+
- Benchmarks cover local WABinary codec paths only. No cross-library speed claim is made.
|
|
163
|
+
|
|
164
|
+
Example encrypted storage:
|
|
165
|
+
|
|
166
|
+
```js
|
|
167
|
+
const { FileStore, EncryptedStore } = require('./src')
|
|
168
|
+
const key = Buffer.from(process.env.KERSIO_STORE_KEY_HEX || '', 'hex')
|
|
169
|
+
if (key.length !== 32) throw new Error('KERSIO_STORE_KEY_HEX wajib 64 digit hex')
|
|
170
|
+
const store = new EncryptedStore(new FileStore('./sessions'), key)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Use a secret manager or environment injection for the master key; never commit it with the source. Use an encrypted store for auth state when storing it through generic Kersio stores.
|
|
174
|
+
|
|
175
|
+
## Security gates — native engine
|
|
176
|
+
|
|
177
|
+
- `Connection` now defaults to `strictServerCertificateVerification: true`. Without `verifyServerCertificate` returning exactly `true`, a synthetic/local Noise handshake may be tested only with explicit `strictServerCertificateVerification: false`. Do not turn this off against a live server.
|
|
178
|
+
- A verifier callback is a hook, not a built-in WhatsApp root certificate chain. Pin and independently test the exact root/intermediate certificates before supplying one.
|
|
179
|
+
- `commitVerifiedPairSuccess()` requires a supplied, independently tested verifier returning `deviceIdentity`, `accountSignature`, and `advHmac` checks, credentials, and a reply node. It is a fail-closed persistence guard, not the cryptographic verifier itself.
|
|
180
|
+
- Native `Signal Protocol`, prekey upload, session crypto and message-node transforms are not implemented end-to-end. Native mode intentionally throws for high-level message use.
|
|
181
|
+
|
|
182
|
+
## Tests & evidence
|
|
183
|
+
|
|
184
|
+
`npm test` covers local unit/mocked tests. This package was **not** connected to a real WhatsApp account during this build. Do not interpret passing unit tests as proof of pairing, media upload, message delivery, app-state sync, or engine interoperability. See `docs/ENGINE-MATRIX.md`, `docs/RESEARCH-BASELINE.md`, and `docs/PROTOCOL-ROADMAP.md`.
|
|
185
|
+
|
|
186
|
+
## Upstream references / licenses
|
|
187
|
+
|
|
188
|
+
- [Baileys](https://github.com/WhiskeySockets/Baileys) — review current v7 migration notes and license before use.
|
|
189
|
+
- [Zapo-JS](https://github.com/vinikjkkj/zapo) — package + optional storage/media/native add-ons; MIT upstream license.
|
|
190
|
+
- [whatsmeow](https://github.com/tulir/whatsmeow) — Go implementation, MPL-2.0 upstream license.
|
|
191
|
+
|
|
192
|
+
KersioSocket is not affiliated with WhatsApp. Respect the respective upstream licenses and WhatsApp's applicable terms. Do not use this library for unsolicited bulk messaging or abusive automation.
|
|
@@ -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,42 @@
|
|
|
1
|
+
# KersioSocket ↔ Go `whatsmeow` bridge contract
|
|
2
|
+
|
|
3
|
+
KersioSocket includes a tested JSON Lines RPC transport in `src/backends/whatsmeow-process.js`. It does **not** bundle a precompiled Go executable or claim that an uncompiled Go sample is production-ready. Build and audit the Go sidecar against the exact `whatsmeow` version you choose, then pass its executable to `createKersioClient({ engine: 'whatsmeow', bridge: { command, args } })`.
|
|
4
|
+
|
|
5
|
+
This is deliberately a transport contract, not an invented WhatsApp protocol implementation. The Go process must use the public `whatsmeow` client, its supported store and its own event handlers. `whatsmeow` has a separate MPL-2.0 license; retain its notices if you distribute its source or binary. KersioSocket itself does not copy its protocol implementation.
|
|
6
|
+
|
|
7
|
+
## Standard input / standard output
|
|
8
|
+
|
|
9
|
+
Each request is one UTF-8 JSON object terminated by `\n`:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{"id":"request-1","method":"connect","params":{"sessionId":"account-a"}}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The sidecar returns one matching response line:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{"id":"request-1","result":{"connected":true}}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Errors have this shape:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{"id":"request-2","error":{"code":"ERR_OPERATION","message":"Readable explanation"}}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Asynchronous events use a line without `id`:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{"event":"messages.upsert","data":{"type":"notify","messages":[]}}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The client currently sends these method names: `connect`, `sendMessage`, `requestPairingCode`, `downloadMedia`, `capabilities`, `invoke`, and `close`. A sidecar may implement additional operations through `invoke`, but the method should be allow-listed by the Go program. Buffers/Uint8Arrays are encoded as `{"$base64":"..."}`; the Go sidecar is responsible for decoding that marker where appropriate. Large media should preferably be streamed or passed by file reference rather than copied through JSONL.
|
|
34
|
+
|
|
35
|
+
## Security and process model
|
|
36
|
+
|
|
37
|
+
- The bridge is spawned with `shell: false`; command and args must be provided separately.
|
|
38
|
+
- Use a private working directory and a dedicated session database per account.
|
|
39
|
+
- Never log QR payloads, pairing codes, auth credentials, or message content to stderr.
|
|
40
|
+
- Return structured errors; do not write non-JSON diagnostics to stdout.
|
|
41
|
+
- The Node adapter bounds the maximum response line and the number of pending RPCs, and times out requests.
|
|
42
|
+
- This bridge contract has a mock-process test. That test proves JSONL transport semantics only, not a live `whatsmeow` connection.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# v0.6.0-dev engine matrix
|
|
2
|
+
|
|
3
|
+
This matrix separates features supplied by an upstream engine from features implemented in KersioSocket's own native transport. A green-looking facade method is never evidence of a successful live server operation.
|
|
4
|
+
|
|
5
|
+
| Capability | Zapo-JS adapter | Baileys adapter | Go `whatsmeow` bridge | Native KersioSocket |
|
|
6
|
+
|---|---|---|---|---|
|
|
7
|
+
| QR / pairing code | Delegated to Zapo; observed auth events normalized | Delegated to Baileys; QR and requestPairingCode mapped | Only if sidecar implements RPC method/events | QR candidate helper only; no verified pair-success implementation |
|
|
8
|
+
| Noise/TLS-like transport trust | Managed by upstream engine | Managed by upstream engine | Managed by whatsmeow in the sidecar | Fail-closed by default; verifier must be injected and independently tested |
|
|
9
|
+
| Signal identity, prekeys, sessions, message crypto | Delegated to Zapo | Delegated to Baileys | Delegated to whatsmeow sidecar | Not implemented end-to-end |
|
|
10
|
+
| Text send and inbound message events | Delegated through `message.send` and event adapter | Delegated through `sendMessage` / `messages.upsert` | Delegated through JSONL RPC | Not supported by native high-level API |
|
|
11
|
+
| Image/video/audio/document/sticker | Delegated; check engine version and media package | Delegated; media upload helpers belong to Baileys | Sidecar must implement media operations | Not implemented |
|
|
12
|
+
| Reactions, polls, edit/delete | Delegated content object; backend support varies | Delegated content object; backend support varies | Sidecar must implement operation | Not implemented |
|
|
13
|
+
| Groups, contacts, app-state/history | Feature detect / backend `invoke()` | Socket methods/events / backend `invoke()` | Sidecar `invoke()` and events | Not implemented end-to-end |
|
|
14
|
+
| Session persistence | Zapo store providers | Baileys auth state/keys | Go store in sidecar | Generic stores and EncryptedStore, but no full native WA auth bundle |
|
|
15
|
+
| Multi-session facade | Supported per distinct session/client | Supported per distinct socket | Supported per distinct bridge process/session | Existing low-level manager retained; live auth not complete |
|
|
16
|
+
| Production live integration evidence in this ZIP | **Not run** | **Not run** | **Not run; sidecar absent** | **Not run; intentionally incomplete** |
|
|
17
|
+
|
|
18
|
+
## Boundaries
|
|
19
|
+
|
|
20
|
+
- The engine adapters normalize the public API surface; they do not exchange live crypto keys between implementations.
|
|
21
|
+
- For one linked WhatsApp account, use one selected engine as the owner of transport, auth, and Signal state. Don't open the same credentials in all engines concurrently.
|
|
22
|
+
- Zapo and Baileys adapter tests use fake EventEmitters. The Go bridge tests use a fake child process. Tests cover event and RPC semantics only.
|
|
23
|
+
- Native Noise certificate verification callback returns a trusted boolean only if the caller has implemented and tested the complete chain. A callback that merely accepts all certificates defeats the default protection.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Protocol roadmap — KersioSocket v0.6.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.
|
|
44
|
+
|
|
45
|
+
## v0.6 integrated engine architecture
|
|
46
|
+
|
|
47
|
+
The high-level facade can select a maintained backend, while keeping the native protocol research layer separate:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
KersioClient / KersioSessionManager
|
|
51
|
+
├─ Zapo-JS WaClient adapter (auth + Signal + messages delegated upstream)
|
|
52
|
+
├─ Baileys socket adapter (auth + Signal + messages delegated upstream)
|
|
53
|
+
├─ Go whatsmeow JSONL-RPC process transport (the Go binary is external)
|
|
54
|
+
└─ native KersioSocket research transport (not a complete live WA engine)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This is an API-level integration, not one merged auth/Signal state machine. A linked account must be owned by one engine at a time. The adapters are tested against mocks; real upstream integration remains a separate verification gate.
|
|
58
|
+
|
|
59
|
+
## v0.6 local improvements
|
|
60
|
+
|
|
61
|
+
- Native Noise handshake defaults to requiring an explicitly supplied certificate verifier; no pinned WhatsApp certificate-chain verifier is included, so strict native connection intentionally fails closed until one is implemented and audited.
|
|
62
|
+
- `commitVerifiedPairSuccess` rejects state transitions unless an external verifier returns successful device identity, account signature and ADV-HMAC checks plus credentials/reply node. The callback contract is a safety gate, not an implementation of the cryptographic verifier.
|
|
63
|
+
- Common client facade, event normalization, message helpers, multi-engine session manager, bounded message archive, and cooperative local file locks.
|
|
64
|
+
- Go adapter implements request/reply correlation, JSONL size bound, request timeout/pending cap, abort handling, structured errors and async events. It does not bundle a Go sidecar or prove live whatsmeow connectivity.
|
|
65
|
+
|
|
66
|
+
## Remaining native protocol gates
|
|
67
|
+
|
|
68
|
+
1. Obtain and pin the current trusted Noise certificate/root chain, implement verification against independent vectors, and confirm behavior against a live-compatible fixture. Do not accept all certificates.
|
|
69
|
+
2. Implement/test verified account pairing: device identity parsing, ADV HMAC, account/device signatures, correct `pair-device-sign` node, and atomic credential update.
|
|
70
|
+
3. Implement a standards-compatible Signal layer with identity/signed prekeys, signature validation, prekey upload, session creation/rotation, group sender keys, and encrypted inbound/outbound message tests.
|
|
71
|
+
4. Implement real WABinary message stanza lifecycle, receipts, offline retry/decryption retry and deduplication.
|
|
72
|
+
5. Add per-backend media upload/download, group APIs, sync/app-state/status/newsletter features, each gated on live or independently captured interoperability tests.
|
|
73
|
+
6. Build/compile the selected Go sidecar against a pinned whatsmeow release and run Go+Node integration tests; the bundled mock only checks bridge protocol semantics.
|
|
74
|
+
7. Run real Redis/Mongo, crash-recovery, cross-process lock, long-duration memory and fair side-by-side latency tests before making production or performance claims.
|
|
@@ -0,0 +1,36 @@
|
|
|
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.
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## v0.6.0-dev adapter research update (2026-10-23)
|
|
29
|
+
|
|
30
|
+
This release adds adapters around public upstream client APIs rather than copying their protocol implementation into KersioSocket:
|
|
31
|
+
|
|
32
|
+
- Baileys public repository/docs: https://github.com/WhiskeySockets/Baileys — adapter targets the current socket factory/event API; upstream notes v7 has breaking changes, so pin versions and run an integration test.
|
|
33
|
+
- Zapo-JS public repository/docs: https://github.com/vinikjkkj/zapo — adapter targets `WaClient`, `connect()`, `message.send()`, and public auth/message events; the chosen store providers are configured by the caller.
|
|
34
|
+
- whatsmeow public repository: https://github.com/tulir/whatsmeow — KersioSocket only provides JSONL-RPC process transport. It does not include a Go implementation or executable; the bridge's transport tests use a fake process.
|
|
35
|
+
|
|
36
|
+
No live account/session was connected during this build. The v0.6 adapter tests demonstrate method forwarding and event normalization, not protocol interoperability or upstream-version compatibility.
|
package/docs/WABINARY.md
ADDED
|
@@ -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,10 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const { makeSocket } = require('../src')
|
|
3
|
+
|
|
4
|
+
// Native transport/protocol research only. It fails closed by default because this
|
|
5
|
+
// project version does not ship a pinned Noise certificate-chain verifier. Do not
|
|
6
|
+
// disable strictServerCertificateVerification for a live server.
|
|
7
|
+
const sock = makeSocket({ autoConnect: false, reconnect: { enabled: false } })
|
|
8
|
+
console.log('[KersioSocket] native research socket created; no network connection was opened.')
|
|
9
|
+
console.log('state:', sock.state, 'stats:', sock.stats())
|
|
10
|
+
sock.end()
|
|
@@ -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,12 @@
|
|
|
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.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## v0.6 adapter notes
|
|
11
|
+
|
|
12
|
+
The Baileys and Zapo-JS adapters invoke their public package APIs at runtime and do not bundle their implementation source. Review the currently installed upstream versions' licenses before redistributing them. The optional Go whatsmeow process bridge is an RPC transport, not a copy or bundle of whatsmeow code; whatsmeow itself is distributed under MPL-2.0. See the upstream license files before distributing a Go sidecar.
|