@kangwifi-pro/waliwa 1.0.0
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/LICENSE +21 -0
- package/README.md +600 -0
- package/dist/advanced/features.d.ts +211 -0
- package/dist/advanced/features.d.ts.map +1 -0
- package/dist/advanced/features.js +671 -0
- package/dist/advanced/features.js.map +1 -0
- package/dist/auth/auth-state.d.ts +89 -0
- package/dist/auth/auth-state.d.ts.map +1 -0
- package/dist/auth/auth-state.js +330 -0
- package/dist/auth/auth-state.js.map +1 -0
- package/dist/auth/pairing-code.d.ts +78 -0
- package/dist/auth/pairing-code.d.ts.map +1 -0
- package/dist/auth/pairing-code.js +191 -0
- package/dist/auth/pairing-code.js.map +1 -0
- package/dist/auth/qr-code.d.ts +60 -0
- package/dist/auth/qr-code.d.ts.map +1 -0
- package/dist/auth/qr-code.js +151 -0
- package/dist/auth/qr-code.js.map +1 -0
- package/dist/calls/handler.d.ts +61 -0
- package/dist/calls/handler.d.ts.map +1 -0
- package/dist/calls/handler.js +117 -0
- package/dist/calls/handler.js.map +1 -0
- package/dist/core/binary.d.ts +74 -0
- package/dist/core/binary.d.ts.map +1 -0
- package/dist/core/binary.js +448 -0
- package/dist/core/binary.js.map +1 -0
- package/dist/core/crypto.d.ts +60 -0
- package/dist/core/crypto.d.ts.map +1 -0
- package/dist/core/crypto.js +170 -0
- package/dist/core/crypto.js.map +1 -0
- package/dist/core/noise.d.ts +106 -0
- package/dist/core/noise.d.ts.map +1 -0
- package/dist/core/noise.js +307 -0
- package/dist/core/noise.js.map +1 -0
- package/dist/events/emitter.d.ts +44 -0
- package/dist/events/emitter.d.ts.map +1 -0
- package/dist/events/emitter.js +79 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/features/index.d.ts +342 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +755 -0
- package/dist/features/index.js.map +1 -0
- package/dist/fixes/index.d.ts +333 -0
- package/dist/fixes/index.d.ts.map +1 -0
- package/dist/fixes/index.js +762 -0
- package/dist/fixes/index.js.map +1 -0
- package/dist/groups/management.d.ts +86 -0
- package/dist/groups/management.d.ts.map +1 -0
- package/dist/groups/management.js +443 -0
- package/dist/groups/management.js.map +1 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +236 -0
- package/dist/index.js.map +1 -0
- package/dist/messages/media.d.ts +93 -0
- package/dist/messages/media.d.ts.map +1 -0
- package/dist/messages/media.js +252 -0
- package/dist/messages/media.js.map +1 -0
- package/dist/messages/message-encoder.d.ts +70 -0
- package/dist/messages/message-encoder.d.ts.map +1 -0
- package/dist/messages/message-encoder.js +453 -0
- package/dist/messages/message-encoder.js.map +1 -0
- package/dist/messages/send.d.ts +101 -0
- package/dist/messages/send.d.ts.map +1 -0
- package/dist/messages/send.js +409 -0
- package/dist/messages/send.js.map +1 -0
- package/dist/recovery/index.d.ts +125 -0
- package/dist/recovery/index.d.ts.map +1 -0
- package/dist/recovery/index.js +584 -0
- package/dist/recovery/index.js.map +1 -0
- package/dist/skdm/index.d.ts +220 -0
- package/dist/skdm/index.d.ts.map +1 -0
- package/dist/skdm/index.js +600 -0
- package/dist/skdm/index.js.map +1 -0
- package/dist/socket/hybrid.d.ts +118 -0
- package/dist/socket/hybrid.d.ts.map +1 -0
- package/dist/socket/hybrid.js +352 -0
- package/dist/socket/hybrid.js.map +1 -0
- package/dist/socket/wa-socket.d.ts +300 -0
- package/dist/socket/wa-socket.d.ts.map +1 -0
- package/dist/socket/wa-socket.js +1094 -0
- package/dist/socket/wa-socket.js.map +1 -0
- package/dist/socket/ws-socket.d.ts +96 -0
- package/dist/socket/ws-socket.d.ts.map +1 -0
- package/dist/socket/ws-socket.js +302 -0
- package/dist/socket/ws-socket.js.map +1 -0
- package/dist/types/index.d.ts +444 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/jid.d.ts +46 -0
- package/dist/utils/jid.d.ts.map +1 -0
- package/dist/utils/jid.js +152 -0
- package/dist/utils/jid.js.map +1 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +79 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/retry.d.ts +43 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +175 -0
- package/dist/utils/retry.js.map +1 -0
- package/docs/API.md +745 -0
- package/docs/ARCHITECTURE.md +307 -0
- package/docs/BAILEYS_FIXES.md +360 -0
- package/docs/FEATURES.md +532 -0
- package/docs/PROTOCOL.md +489 -0
- package/docs/RECOVERY.md +409 -0
- package/docs/SKDM.md +233 -0
- package/examples/ai-bot/index.ts +479 -0
- package/examples/ai-bot/package.json +17 -0
- package/examples/echo-bot/index.ts +171 -0
- package/examples/echo-bot/package.json +18 -0
- package/examples/group-bot/index.ts +557 -0
- package/examples/group-bot/package.json +17 -0
- package/examples/rest-gateway/index.ts +499 -0
- package/examples/rest-gateway/package.json +19 -0
- package/package.json +75 -0
- package/src/advanced/features.ts +817 -0
- package/src/auth/auth-state.ts +342 -0
- package/src/auth/pairing-code.ts +246 -0
- package/src/auth/qr-code.ts +191 -0
- package/src/calls/handler.ts +153 -0
- package/src/core/binary.ts +464 -0
- package/src/core/crypto.ts +189 -0
- package/src/core/noise.ts +406 -0
- package/src/events/emitter.ts +88 -0
- package/src/features/index.ts +921 -0
- package/src/fixes/index.ts +882 -0
- package/src/groups/management.ts +497 -0
- package/src/index.ts +274 -0
- package/src/messages/media.ts +372 -0
- package/src/messages/message-encoder.ts +520 -0
- package/src/messages/send.ts +521 -0
- package/src/recovery/index.ts +704 -0
- package/src/skdm/index.ts +693 -0
- package/src/socket/hybrid.ts +414 -0
- package/src/socket/wa-socket.ts +1347 -0
- package/src/socket/ws-socket.ts +355 -0
- package/src/types/index.ts +457 -0
- package/src/utils/jid.ts +156 -0
- package/src/utils/logger.ts +84 -0
- package/src/utils/retry.ts +205 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Waliwa - Crypto utilities
|
|
4
|
+
* Hybrid approach: menggunakan @noble/curves & @noble/hashes untuk primitives
|
|
5
|
+
* Manual implementasi untuk WhatsApp-specific encoding (noise handshake, message framing)
|
|
6
|
+
*
|
|
7
|
+
* RAM optimization: gunakan Uint8Array (bukan Buffer) di mana memungkinkan untuk
|
|
8
|
+
* hindari overhead V8 Buffer pool.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.generateCurveKeyPair = generateCurveKeyPair;
|
|
12
|
+
exports.curveSharedSecret = curveSharedSecret;
|
|
13
|
+
exports.curveSign = curveSign;
|
|
14
|
+
exports.curveVerify = curveVerify;
|
|
15
|
+
exports.sha256Hash = sha256Hash;
|
|
16
|
+
exports.sha512Hash = sha512Hash;
|
|
17
|
+
exports.sha1Hash = sha1Hash;
|
|
18
|
+
exports.hmacSha256 = hmacSha256;
|
|
19
|
+
exports.hmacSha512 = hmacSha512;
|
|
20
|
+
exports.hkdfDerive = hkdfDerive;
|
|
21
|
+
exports.createAESCipher = createAESCipher;
|
|
22
|
+
exports.aesEncryptCBC = aesEncryptCBC;
|
|
23
|
+
exports.aesDecryptCBC = aesDecryptCBC;
|
|
24
|
+
exports.getRandomBytes = getRandomBytes;
|
|
25
|
+
exports.concatBytes = concatBytes;
|
|
26
|
+
exports.areBytesEqual = areBytesEqual;
|
|
27
|
+
exports.constantTimeEqual = constantTimeEqual;
|
|
28
|
+
const ed25519_1 = require("@noble/curves/ed25519");
|
|
29
|
+
const sha256_1 = require("@noble/hashes/sha256");
|
|
30
|
+
const sha512_1 = require("@noble/hashes/sha512");
|
|
31
|
+
const hmac_1 = require("@noble/hashes/hmac");
|
|
32
|
+
const sha1_1 = require("@noble/hashes/sha1");
|
|
33
|
+
const aes_1 = require("@noble/ciphers/aes");
|
|
34
|
+
const crypto_1 = require("crypto");
|
|
35
|
+
const hkdf_1 = require("@noble/hashes/hkdf");
|
|
36
|
+
/**
|
|
37
|
+
* Generate Curve25519 key pair untuk Noise Protocol / Signal keys
|
|
38
|
+
* RAM-friendly: gunakan direct x25519 dari @noble/curves (no bindings).
|
|
39
|
+
*/
|
|
40
|
+
function generateCurveKeyPair() {
|
|
41
|
+
const privateKey = (0, crypto_1.randomBytes)(32);
|
|
42
|
+
const publicKey = ed25519_1.x25519.getPublicKey(privateKey);
|
|
43
|
+
return { private: privateKey, public: publicKey };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* X25519 ECDH - compute shared secret
|
|
47
|
+
*/
|
|
48
|
+
function curveSharedSecret(privateKey, publicKey) {
|
|
49
|
+
return ed25519_1.x25519.getSharedSecret(privateKey, publicKey);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Sign data dengan Ed25519 (untuk Signal signed pre-keys)
|
|
53
|
+
*/
|
|
54
|
+
function curveSign(privateKey, data) {
|
|
55
|
+
// Use ed25519 sign via noble - we use it for identity signing
|
|
56
|
+
const { ed25519 } = require('@noble/curves/ed25519');
|
|
57
|
+
return ed25519.sign(data, privateKey);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Verify Ed25519 signature
|
|
61
|
+
*/
|
|
62
|
+
function curveVerify(publicKey, data, signature) {
|
|
63
|
+
const { ed25519 } = require('@noble/curves/ed25519');
|
|
64
|
+
try {
|
|
65
|
+
return ed25519.verify(signature, data, publicKey);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// ============== Hashing ==============
|
|
72
|
+
function sha256Hash(data) {
|
|
73
|
+
return (0, sha256_1.sha256)(data);
|
|
74
|
+
}
|
|
75
|
+
function sha512Hash(data) {
|
|
76
|
+
return (0, sha512_1.sha512)(data);
|
|
77
|
+
}
|
|
78
|
+
function sha1Hash(data) {
|
|
79
|
+
return (0, sha1_1.sha1)(data);
|
|
80
|
+
}
|
|
81
|
+
function hmacSha256(key, data) {
|
|
82
|
+
return hmac_1.hmac.create(sha256_1.sha256, key).update(data).digest();
|
|
83
|
+
}
|
|
84
|
+
function hmacSha512(key, data) {
|
|
85
|
+
return hmac_1.hmac.create(sha512_1.sha512, key).update(data).digest();
|
|
86
|
+
}
|
|
87
|
+
// ============== HKDF (RFC 5869) ==============
|
|
88
|
+
/**
|
|
89
|
+
* HKDF - HMAC-based Key Derivation Function
|
|
90
|
+
* WhatsApp menggunakan HKDF extensively untuk derive keys dari shared secrets
|
|
91
|
+
*/
|
|
92
|
+
function hkdfDerive(ikm, salt, info, length) {
|
|
93
|
+
const prk = hmacSha256(salt.length === 0 ? new Uint8Array(32) : salt, ikm);
|
|
94
|
+
return (0, hkdf_1.hkdf)(sha256_1.sha256, prk, salt, info, length);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* AES-256-GCM cipher (sebuah komponen inti WA message encryption)
|
|
98
|
+
*/
|
|
99
|
+
function createAESCipher(key) {
|
|
100
|
+
return {
|
|
101
|
+
encrypt(plaintext, iv, aad) {
|
|
102
|
+
const cipher = (0, aes_1.gcm)(key, iv, aad);
|
|
103
|
+
const sealed = cipher.encrypt(plaintext);
|
|
104
|
+
// GCM output dari @noble: ciphertext + tag (16 byte) di akhir
|
|
105
|
+
const ciphertext = sealed.subarray(0, sealed.length - 16);
|
|
106
|
+
const tag = sealed.subarray(sealed.length - 16);
|
|
107
|
+
return { ciphertext, tag };
|
|
108
|
+
},
|
|
109
|
+
decrypt(ciphertext, iv, tag, aad) {
|
|
110
|
+
const cipher = (0, aes_1.gcm)(key, iv, aad);
|
|
111
|
+
const sealed = new Uint8Array(ciphertext.length + tag.length);
|
|
112
|
+
sealed.set(ciphertext, 0);
|
|
113
|
+
sealed.set(tag, ciphertext.length);
|
|
114
|
+
return cipher.decrypt(sealed);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
// ============== AES-256-CBC (untuk media encryption) ==============
|
|
119
|
+
function aesEncryptCBC(plaintext, key, iv) {
|
|
120
|
+
// PKCS7 padding
|
|
121
|
+
const blockSize = 16;
|
|
122
|
+
const padLength = blockSize - (plaintext.length % blockSize);
|
|
123
|
+
const padded = new Uint8Array(plaintext.length + padLength);
|
|
124
|
+
padded.set(plaintext, 0);
|
|
125
|
+
for (let i = plaintext.length; i < padded.length; i++) {
|
|
126
|
+
padded[i] = padLength;
|
|
127
|
+
}
|
|
128
|
+
// Use Node crypto for CBC (Noble doesn't expose CBC)
|
|
129
|
+
const { createCipheriv } = require('crypto');
|
|
130
|
+
const cipher = createCipheriv('aes-256-cbc', Buffer.from(key), Buffer.from(iv));
|
|
131
|
+
return new Uint8Array(Buffer.concat([cipher.update(Buffer.from(padded)), cipher.final()]));
|
|
132
|
+
}
|
|
133
|
+
function aesDecryptCBC(ciphertext, key, iv) {
|
|
134
|
+
const { createDecipheriv } = require('crypto');
|
|
135
|
+
const decipher = createDecipheriv('aes-256-cbc', Buffer.from(key), Buffer.from(iv));
|
|
136
|
+
const padded = Buffer.concat([decipher.update(Buffer.from(ciphertext)), decipher.final()]);
|
|
137
|
+
// Remove PKCS7 padding
|
|
138
|
+
const padLength = padded[padded.length - 1];
|
|
139
|
+
return new Uint8Array(padded.subarray(0, padded.length - padLength));
|
|
140
|
+
}
|
|
141
|
+
// ============== Random ==============
|
|
142
|
+
function getRandomBytes(length) {
|
|
143
|
+
return new Uint8Array((0, crypto_1.randomBytes)(length));
|
|
144
|
+
}
|
|
145
|
+
// ============== Helpers ==============
|
|
146
|
+
function concatBytes(...arrays) {
|
|
147
|
+
const total = arrays.reduce((sum, a) => sum + a.length, 0);
|
|
148
|
+
const result = new Uint8Array(total);
|
|
149
|
+
let offset = 0;
|
|
150
|
+
for (const arr of arrays) {
|
|
151
|
+
result.set(arr, offset);
|
|
152
|
+
offset += arr.length;
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
function areBytesEqual(a, b) {
|
|
157
|
+
if (a.length !== b.length)
|
|
158
|
+
return false;
|
|
159
|
+
let diff = 0;
|
|
160
|
+
for (let i = 0; i < a.length; i++)
|
|
161
|
+
diff |= a[i] ^ b[i];
|
|
162
|
+
return diff === 0;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Constant-time comparison untuk hmac verification
|
|
166
|
+
*/
|
|
167
|
+
function constantTimeEqual(a, b) {
|
|
168
|
+
return areBytesEqual(a, b);
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/core/crypto.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Waliwa - Noise Protocol XX handshake implementation
|
|
3
|
+
*
|
|
4
|
+
* WhatsApp Web Multi-Device menggunakan Noise Protocol Framework (XX pattern)
|
|
5
|
+
* untuk establish secure channel antara client dan WhatsApp server.
|
|
6
|
+
*
|
|
7
|
+
* Pattern XX (lihat noiseprotocol.com):
|
|
8
|
+
* <- e
|
|
9
|
+
* -> e, ee, s, es
|
|
10
|
+
* <- s, se
|
|
11
|
+
*
|
|
12
|
+
* Handshake ini menghasilkan encryption key untuk semua komunikasi WebSocket selanjutnya.
|
|
13
|
+
*
|
|
14
|
+
* Original implementation - tidak copy dari Baileys/ZapoJS.
|
|
15
|
+
*/
|
|
16
|
+
import { KeyPair } from './crypto.js';
|
|
17
|
+
export declare class NoiseHandshake {
|
|
18
|
+
private state;
|
|
19
|
+
private cipher;
|
|
20
|
+
private readonly cipherKeyLen;
|
|
21
|
+
private readonly nonceLen;
|
|
22
|
+
constructor(staticKey?: KeyPair, initiator?: boolean);
|
|
23
|
+
private initializeSymmetric;
|
|
24
|
+
/**
|
|
25
|
+
* Mix key into chaining key + derive new cipher key
|
|
26
|
+
*/
|
|
27
|
+
private mixKey;
|
|
28
|
+
/**
|
|
29
|
+
* Mix hash data into handshake hash
|
|
30
|
+
*/
|
|
31
|
+
private mixHash;
|
|
32
|
+
/**
|
|
33
|
+
* Encrypt dengan handshake key
|
|
34
|
+
*/
|
|
35
|
+
private encryptWithHash;
|
|
36
|
+
/**
|
|
37
|
+
* Decrypt dengan handshake key
|
|
38
|
+
*/
|
|
39
|
+
private decryptWithHash;
|
|
40
|
+
/**
|
|
41
|
+
* Generate GCM nonce dari counter (big-endian, 4-byte prefix zero)
|
|
42
|
+
*/
|
|
43
|
+
private generateNonce;
|
|
44
|
+
/**
|
|
45
|
+
* Step 1: Send ephemeral key (initiator -> responder)
|
|
46
|
+
* Output: bytes untuk dikirim ke server
|
|
47
|
+
*/
|
|
48
|
+
writeEphemeral(): Uint8Array;
|
|
49
|
+
/**
|
|
50
|
+
* Step 2: Receive ephemeral + static + EE + ES from responder
|
|
51
|
+
*/
|
|
52
|
+
readResponderHandshake(payload: Uint8Array): {
|
|
53
|
+
plaintext: Uint8Array;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Step 3: Send our static + ES + payload (initiator -> responder)
|
|
57
|
+
*/
|
|
58
|
+
writeInitiatorHandshake(payload: Uint8Array): Uint8Array;
|
|
59
|
+
/**
|
|
60
|
+
* Finalize handshake - split prk into send/recv keys
|
|
61
|
+
*/
|
|
62
|
+
finalize(): {
|
|
63
|
+
sendKey: Uint8Array;
|
|
64
|
+
recvKey: Uint8Array;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Encrypt a frame post-handshake menggunakan traffic keys
|
|
68
|
+
*/
|
|
69
|
+
static encryptFrame(key: Uint8Array, counter: number, plaintext: Uint8Array): Uint8Array;
|
|
70
|
+
/**
|
|
71
|
+
* Decrypt a frame post-handshake
|
|
72
|
+
*/
|
|
73
|
+
static decryptFrame(key: Uint8Array, counter: number, ciphertext: Uint8Array): Uint8Array;
|
|
74
|
+
/**
|
|
75
|
+
* Encode WA noise frame: [WA_HEADER] [VERSION] [LENGTH:3] [PAYLOAD]
|
|
76
|
+
*/
|
|
77
|
+
static encodeFrame(payload: Uint8Array): Uint8Array;
|
|
78
|
+
/**
|
|
79
|
+
* Encode WA client payload (untuk handshake init message)
|
|
80
|
+
* Format: [ephemeral_pubkey:32] [static_encrypted] [payload_encrypted]
|
|
81
|
+
*/
|
|
82
|
+
static encodeClientHello(ephemeralPub: Uint8Array, encryptedStatic: Uint8Array, encryptedPayload: Uint8Array): Uint8Array;
|
|
83
|
+
/**
|
|
84
|
+
* Build client hello untuk initial connection
|
|
85
|
+
*/
|
|
86
|
+
buildClientHello(clientPayload: Uint8Array): Uint8Array;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Traffic cipher untuk encrypt/decrypt frames setelah handshake done
|
|
90
|
+
*/
|
|
91
|
+
export declare class TrafficCipher {
|
|
92
|
+
private sendKey;
|
|
93
|
+
private recvKey;
|
|
94
|
+
private sendCounter;
|
|
95
|
+
private recvCounter;
|
|
96
|
+
constructor(sendKey: Uint8Array, recvKey: Uint8Array);
|
|
97
|
+
encrypt(plaintext: Uint8Array): Uint8Array;
|
|
98
|
+
decrypt(ciphertext: Uint8Array): Uint8Array;
|
|
99
|
+
reset(): void;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Build initial client payload untuk WA Web multi-device connect
|
|
103
|
+
* Berisi info browser, version, dan props
|
|
104
|
+
*/
|
|
105
|
+
export declare function buildClientPayload(browser: [string, string, string]): Uint8Array;
|
|
106
|
+
//# sourceMappingURL=noise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noise.d.ts","sourceRoot":"","sources":["../../src/core/noise.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAUL,OAAO,EAER,MAAM,aAAa,CAAC;AAyCrB,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAM;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAM;gBAEnB,SAAS,CAAC,EAAE,OAAO,EAAE,SAAS,GAAE,OAAc;IAe1D,OAAO,CAAC,mBAAmB;IAS3B;;OAEG;IACH,OAAO,CAAC,MAAM;IAad;;OAEG;IACH,OAAO,CAAC,OAAO;IAIf;;OAEG;IACH,OAAO,CAAC,eAAe;IAcvB;;OAEG;IACH,OAAO,CAAC,eAAe;IAevB;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB;;;OAGG;IACI,cAAc,IAAI,UAAU;IAQnC;;OAEG;IACI,sBAAsB,CAAC,OAAO,EAAE,UAAU,GAAG;QAAE,SAAS,EAAE,UAAU,CAAA;KAAE;IA6B7E;;OAEG;IACI,uBAAuB,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU;IAmB/D;;OAEG;IACI,QAAQ,IAAI;QAAE,OAAO,EAAE,UAAU,CAAC;QAAC,OAAO,EAAE,UAAU,CAAA;KAAE;IAe/D;;OAEG;WACW,YAAY,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,UAAU,GACpB,UAAU;IAUb;;OAEG;WACW,YAAY,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,UAAU,GACrB,UAAU;IAcb;;OAEG;WACW,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU;IAkB1D;;;OAGG;WACW,iBAAiB,CAC7B,YAAY,EAAE,UAAU,EACxB,eAAe,EAAE,UAAU,EAC3B,gBAAgB,EAAE,UAAU,GAC3B,UAAU;IAIb;;OAEG;IACI,gBAAgB,CAAC,aAAa,EAAE,UAAU,GAAG,UAAU;CAM/D;AAID;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,WAAW,CAAa;gBAEpB,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAKpD,OAAO,CAAC,SAAS,EAAE,UAAU,GAAG,UAAU;IAM1C,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU;IAM3C,KAAK;CAIN;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,CA4BhF"}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Waliwa - Noise Protocol XX handshake implementation
|
|
4
|
+
*
|
|
5
|
+
* WhatsApp Web Multi-Device menggunakan Noise Protocol Framework (XX pattern)
|
|
6
|
+
* untuk establish secure channel antara client dan WhatsApp server.
|
|
7
|
+
*
|
|
8
|
+
* Pattern XX (lihat noiseprotocol.com):
|
|
9
|
+
* <- e
|
|
10
|
+
* -> e, ee, s, es
|
|
11
|
+
* <- s, se
|
|
12
|
+
*
|
|
13
|
+
* Handshake ini menghasilkan encryption key untuk semua komunikasi WebSocket selanjutnya.
|
|
14
|
+
*
|
|
15
|
+
* Original implementation - tidak copy dari Baileys/ZapoJS.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.TrafficCipher = exports.NoiseHandshake = void 0;
|
|
19
|
+
exports.buildClientPayload = buildClientPayload;
|
|
20
|
+
const crypto_js_1 = require("./crypto.js");
|
|
21
|
+
// ============== Noise Constants ==============
|
|
22
|
+
/** Noise protocol name - WhatsApp menggunakan "Noise_XX_25519_AESGCM_SHA256" */
|
|
23
|
+
const NOISE_PROTOCOL_NAME = 'Noise_XX_25519_AESGCM_SHA256';
|
|
24
|
+
const NOISE_HANDSHAKE_DONE = 'Noise_XX_25519_AESGCM_SHA256_handshake_done';
|
|
25
|
+
const HKDF_INFO = new TextEncoder().encode(NOISE_PROTOCOL_NAME);
|
|
26
|
+
// WhatsApp specific constants
|
|
27
|
+
const WA_NOISE_HEADER = new Uint8Array([0x57, 0x41]); // "WA" - 2 bytes prefix
|
|
28
|
+
const WA_VERSION = new Uint8Array([0x05, 0x2d]); // Version 2.45 encoded
|
|
29
|
+
// Max ciphertext size untuk WA frames
|
|
30
|
+
const MAX_FRAME_SIZE = 1024 * 1024; // 1 MB
|
|
31
|
+
// ============== Noise Handshake ==============
|
|
32
|
+
class NoiseHandshake {
|
|
33
|
+
state;
|
|
34
|
+
cipher;
|
|
35
|
+
cipherKeyLen = 32;
|
|
36
|
+
nonceLen = 12;
|
|
37
|
+
constructor(staticKey, initiator = true) {
|
|
38
|
+
this.state = {
|
|
39
|
+
ss: this.initializeSymmetric(),
|
|
40
|
+
s: staticKey ?? (0, crypto_js_1.generateCurveKeyPair)(),
|
|
41
|
+
e: (0, crypto_js_1.generateCurveKeyPair)(),
|
|
42
|
+
rs: null,
|
|
43
|
+
re: null,
|
|
44
|
+
initiator,
|
|
45
|
+
messagePattern: ['e', 'e', 'ee', 's', 'es', 's', 'se']
|
|
46
|
+
};
|
|
47
|
+
this.cipher = (0, crypto_js_1.createAESCipher)(new Uint8Array(32));
|
|
48
|
+
// Mix protocol name into hash
|
|
49
|
+
this.state.ss.h = (0, crypto_js_1.sha256Hash)(new TextEncoder().encode(NOISE_PROTOCOL_NAME));
|
|
50
|
+
}
|
|
51
|
+
initializeSymmetric() {
|
|
52
|
+
const protocolHash = (0, crypto_js_1.sha256Hash)(new TextEncoder().encode(NOISE_PROTOCOL_NAME));
|
|
53
|
+
return {
|
|
54
|
+
ck: protocolHash,
|
|
55
|
+
h: protocolHash,
|
|
56
|
+
cipher: { key: null, nonce: 0 }
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Mix key into chaining key + derive new cipher key
|
|
61
|
+
*/
|
|
62
|
+
mixKey(inputKey) {
|
|
63
|
+
const derived = (0, crypto_js_1.hkdfDerive)(inputKey, this.state.ss.ck, new Uint8Array(0), 64);
|
|
64
|
+
// Split into 32-byte ck and 32-byte key
|
|
65
|
+
this.state.ss.ck = derived.subarray(0, 32);
|
|
66
|
+
this.state.ss.cipher.key = derived.subarray(32, 64);
|
|
67
|
+
this.state.ss.cipher.nonce = 0;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Mix hash data into handshake hash
|
|
71
|
+
*/
|
|
72
|
+
mixHash(data) {
|
|
73
|
+
this.state.ss.h = (0, crypto_js_1.sha256Hash)((0, crypto_js_1.concatBytes)(this.state.ss.h, data));
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Encrypt dengan handshake key
|
|
77
|
+
*/
|
|
78
|
+
encryptWithHash(plaintext) {
|
|
79
|
+
if (!this.state.ss.cipher.key) {
|
|
80
|
+
return plaintext;
|
|
81
|
+
}
|
|
82
|
+
const iv = this.generateNonce(this.state.ss.cipher.nonce);
|
|
83
|
+
const { ciphertext, tag } = this.cipher.encrypt(plaintext, iv, this.state.ss.h);
|
|
84
|
+
this.state.ss.cipher.nonce++;
|
|
85
|
+
return (0, crypto_js_1.concatBytes)(ciphertext, tag);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Decrypt dengan handshake key
|
|
89
|
+
*/
|
|
90
|
+
decryptWithHash(ciphertext) {
|
|
91
|
+
if (!this.state.ss.cipher.key) {
|
|
92
|
+
return ciphertext;
|
|
93
|
+
}
|
|
94
|
+
if (ciphertext.length < 16) {
|
|
95
|
+
throw new Error('Ciphertext too short');
|
|
96
|
+
}
|
|
97
|
+
const iv = this.generateNonce(this.state.ss.cipher.nonce);
|
|
98
|
+
const ct = ciphertext.subarray(0, ciphertext.length - 16);
|
|
99
|
+
const tag = ciphertext.subarray(ciphertext.length - 16);
|
|
100
|
+
const plaintext = this.cipher.decrypt(ct, iv, tag, this.state.ss.h);
|
|
101
|
+
this.state.ss.cipher.nonce++;
|
|
102
|
+
return plaintext;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Generate GCM nonce dari counter (big-endian, 4-byte prefix zero)
|
|
106
|
+
*/
|
|
107
|
+
generateNonce(counter) {
|
|
108
|
+
const nonce = new Uint8Array(12);
|
|
109
|
+
// Last 8 bytes = counter (big-endian)
|
|
110
|
+
const view = new DataView(nonce.buffer);
|
|
111
|
+
view.setUint32(4, Math.floor(counter / 0x100000000));
|
|
112
|
+
view.setUint32(8, counter & 0xffffffff);
|
|
113
|
+
return nonce;
|
|
114
|
+
}
|
|
115
|
+
// ============== Public Handshake Methods ==============
|
|
116
|
+
/**
|
|
117
|
+
* Step 1: Send ephemeral key (initiator -> responder)
|
|
118
|
+
* Output: bytes untuk dikirim ke server
|
|
119
|
+
*/
|
|
120
|
+
writeEphemeral() {
|
|
121
|
+
const e = (0, crypto_js_1.generateCurveKeyPair)();
|
|
122
|
+
this.state.e = e;
|
|
123
|
+
this.mixHash(e.public);
|
|
124
|
+
this.mixKey(e.public);
|
|
125
|
+
return e.public;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Step 2: Receive ephemeral + static + EE + ES from responder
|
|
129
|
+
*/
|
|
130
|
+
readResponderHandshake(payload) {
|
|
131
|
+
// First 32 bytes = ephemeral key
|
|
132
|
+
if (payload.length < 32)
|
|
133
|
+
throw new Error('Handshake too short');
|
|
134
|
+
const re = payload.subarray(0, 32);
|
|
135
|
+
this.state.re = re;
|
|
136
|
+
this.mixHash(re);
|
|
137
|
+
this.mixKey(re);
|
|
138
|
+
// Ephemeral-ephemeral DH
|
|
139
|
+
const ee = (0, crypto_js_1.curveSharedSecret)(this.state.e.private, re);
|
|
140
|
+
this.mixKey(ee);
|
|
141
|
+
// Next: encrypted static key + payload
|
|
142
|
+
const encryptedStatic = payload.subarray(32);
|
|
143
|
+
const remoteStatic = this.decryptWithHash(encryptedStatic);
|
|
144
|
+
this.state.rs = remoteStatic.subarray(0, 32);
|
|
145
|
+
this.mixHash(remoteStatic);
|
|
146
|
+
// Ephemeral-static DH
|
|
147
|
+
const es = (0, crypto_js_1.curveSharedSecret)(this.state.e.private, remoteStatic);
|
|
148
|
+
this.mixKey(es);
|
|
149
|
+
// Remaining: encrypted payload
|
|
150
|
+
const encryptedPayload = remoteStatic.subarray(32);
|
|
151
|
+
const payload2 = this.decryptWithHash(encryptedPayload);
|
|
152
|
+
return { plaintext: payload2 };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Step 3: Send our static + ES + payload (initiator -> responder)
|
|
156
|
+
*/
|
|
157
|
+
writeInitiatorHandshake(payload) {
|
|
158
|
+
// Send ephemeral already done in step 1
|
|
159
|
+
// Now send static + ES + payload, all encrypted with current handshake key
|
|
160
|
+
// Encrypt our static key
|
|
161
|
+
const encryptedStatic = this.encryptWithHash(this.state.s.public);
|
|
162
|
+
this.mixHash(this.state.s.public);
|
|
163
|
+
// Static-ephemeral DH (us.remote ephemeral)
|
|
164
|
+
if (!this.state.re)
|
|
165
|
+
throw new Error('No remote ephemeral');
|
|
166
|
+
const se = (0, crypto_js_1.curveSharedSecret)(this.state.s.private, this.state.re);
|
|
167
|
+
this.mixKey(se);
|
|
168
|
+
// Encrypt payload
|
|
169
|
+
const encryptedPayload = this.encryptWithHash(payload);
|
|
170
|
+
return (0, crypto_js_1.concatBytes)(encryptedStatic, encryptedPayload);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Finalize handshake - split prk into send/recv keys
|
|
174
|
+
*/
|
|
175
|
+
finalize() {
|
|
176
|
+
const derived = (0, crypto_js_1.hkdfDerive)(new Uint8Array(0), this.state.ss.ck, new TextEncoder().encode(NOISE_HANDSHAKE_DONE), 64);
|
|
177
|
+
return {
|
|
178
|
+
sendKey: derived.subarray(0, 32),
|
|
179
|
+
recvKey: derived.subarray(32, 64)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// ============== Post-handshake AEAD ==============
|
|
183
|
+
/**
|
|
184
|
+
* Encrypt a frame post-handshake menggunakan traffic keys
|
|
185
|
+
*/
|
|
186
|
+
static encryptFrame(key, counter, plaintext) {
|
|
187
|
+
const cipher = (0, crypto_js_1.createAESCipher)(key);
|
|
188
|
+
const iv = new Uint8Array(12);
|
|
189
|
+
const view = new DataView(iv.buffer);
|
|
190
|
+
view.setUint32(4, Math.floor(counter / 0x100000000));
|
|
191
|
+
view.setUint32(8, counter & 0xffffffff);
|
|
192
|
+
const { ciphertext, tag } = cipher.encrypt(plaintext, iv);
|
|
193
|
+
return (0, crypto_js_1.concatBytes)(ciphertext, tag);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Decrypt a frame post-handshake
|
|
197
|
+
*/
|
|
198
|
+
static decryptFrame(key, counter, ciphertext) {
|
|
199
|
+
if (ciphertext.length < 16)
|
|
200
|
+
throw new Error('Frame too short');
|
|
201
|
+
const cipher = (0, crypto_js_1.createAESCipher)(key);
|
|
202
|
+
const iv = new Uint8Array(12);
|
|
203
|
+
const view = new DataView(iv.buffer);
|
|
204
|
+
view.setUint32(4, Math.floor(counter / 0x100000000));
|
|
205
|
+
view.setUint32(8, counter & 0xffffffff);
|
|
206
|
+
const ct = ciphertext.subarray(0, ciphertext.length - 16);
|
|
207
|
+
const tag = ciphertext.subarray(ciphertext.length - 16);
|
|
208
|
+
return cipher.decrypt(ct, iv, tag);
|
|
209
|
+
}
|
|
210
|
+
// ============== Frame helpers ==============
|
|
211
|
+
/**
|
|
212
|
+
* Encode WA noise frame: [WA_HEADER] [VERSION] [LENGTH:3] [PAYLOAD]
|
|
213
|
+
*/
|
|
214
|
+
static encodeFrame(payload) {
|
|
215
|
+
const len = payload.length;
|
|
216
|
+
const header = new Uint8Array(3 + 2 + 2); // WA + version + 16-bit length placeholder (3 byte for >64KB)
|
|
217
|
+
// WA header
|
|
218
|
+
header[0] = 0x57; // 'W'
|
|
219
|
+
header[1] = 0x41; // 'A'
|
|
220
|
+
// Version
|
|
221
|
+
header[2] = 0x05;
|
|
222
|
+
header[3] = 0x2d;
|
|
223
|
+
// Length (3 bytes big-endian for up to 16MB)
|
|
224
|
+
header[4] = (len >> 16) & 0xff;
|
|
225
|
+
header[5] = (len >> 8) & 0xff;
|
|
226
|
+
header[6] = len & 0xff;
|
|
227
|
+
return (0, crypto_js_1.concatBytes)(header.subarray(0, 7), payload);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Encode WA client payload (untuk handshake init message)
|
|
231
|
+
* Format: [ephemeral_pubkey:32] [static_encrypted] [payload_encrypted]
|
|
232
|
+
*/
|
|
233
|
+
static encodeClientHello(ephemeralPub, encryptedStatic, encryptedPayload) {
|
|
234
|
+
return (0, crypto_js_1.concatBytes)(ephemeralPub, encryptedStatic, encryptedPayload);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Build client hello untuk initial connection
|
|
238
|
+
*/
|
|
239
|
+
buildClientHello(clientPayload) {
|
|
240
|
+
// Step 1 + 3 combined for client hello
|
|
241
|
+
const ephemeral = this.writeEphemeral();
|
|
242
|
+
const encrypted = this.writeInitiatorHandshake(clientPayload);
|
|
243
|
+
return (0, crypto_js_1.concatBytes)(ephemeral, encrypted);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
exports.NoiseHandshake = NoiseHandshake;
|
|
247
|
+
// ============== Traffic Cipher (post-handshake) ==============
|
|
248
|
+
/**
|
|
249
|
+
* Traffic cipher untuk encrypt/decrypt frames setelah handshake done
|
|
250
|
+
*/
|
|
251
|
+
class TrafficCipher {
|
|
252
|
+
sendKey;
|
|
253
|
+
recvKey;
|
|
254
|
+
sendCounter = 0;
|
|
255
|
+
recvCounter = 0;
|
|
256
|
+
constructor(sendKey, recvKey) {
|
|
257
|
+
this.sendKey = sendKey;
|
|
258
|
+
this.recvKey = recvKey;
|
|
259
|
+
}
|
|
260
|
+
encrypt(plaintext) {
|
|
261
|
+
const result = NoiseHandshake.encryptFrame(this.sendKey, this.sendCounter, plaintext);
|
|
262
|
+
this.sendCounter++;
|
|
263
|
+
return result;
|
|
264
|
+
}
|
|
265
|
+
decrypt(ciphertext) {
|
|
266
|
+
const plaintext = NoiseHandshake.decryptFrame(this.recvKey, this.recvCounter, ciphertext);
|
|
267
|
+
this.recvCounter++;
|
|
268
|
+
return plaintext;
|
|
269
|
+
}
|
|
270
|
+
reset() {
|
|
271
|
+
this.sendCounter = 0;
|
|
272
|
+
this.recvCounter = 0;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
exports.TrafficCipher = TrafficCipher;
|
|
276
|
+
// ============== Client Payload Builder ==============
|
|
277
|
+
/**
|
|
278
|
+
* Build initial client payload untuk WA Web multi-device connect
|
|
279
|
+
* Berisi info browser, version, dan props
|
|
280
|
+
*/
|
|
281
|
+
function buildClientPayload(browser) {
|
|
282
|
+
// Encoded sebagai WA binary node
|
|
283
|
+
const enc = new TextEncoder();
|
|
284
|
+
const parts = [];
|
|
285
|
+
// Browser info: [name, short_name, version]
|
|
286
|
+
parts.push(enc.encode(browser[0]));
|
|
287
|
+
parts.push(enc.encode(browser[1]));
|
|
288
|
+
parts.push(enc.encode(browser[2]));
|
|
289
|
+
// Pairing static key (32 bytes) - atau empty jika belum ada
|
|
290
|
+
// This is generated at first connection and stored in creds
|
|
291
|
+
// For first-time: generate new
|
|
292
|
+
const pairingKey = (0, crypto_js_1.generateCurveKeyPair)();
|
|
293
|
+
parts.push(pairingKey.public);
|
|
294
|
+
// Compute total length
|
|
295
|
+
let totalLen = 0;
|
|
296
|
+
for (const p of parts)
|
|
297
|
+
totalLen += p.length;
|
|
298
|
+
// Prepend each part with length byte (assuming < 256)
|
|
299
|
+
const result = [];
|
|
300
|
+
for (const p of parts) {
|
|
301
|
+
result.push(p.length);
|
|
302
|
+
for (let i = 0; i < p.length; i++)
|
|
303
|
+
result.push(p[i]);
|
|
304
|
+
}
|
|
305
|
+
return new Uint8Array(result);
|
|
306
|
+
}
|
|
307
|
+
//# sourceMappingURL=noise.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noise.js","sourceRoot":"","sources":["../../src/core/noise.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Waliwa - Event emitter untuk WebSocket events
|
|
3
|
+
* Typed event emitter untuk WhatsApp events (messages, presence, calls, dll)
|
|
4
|
+
*
|
|
5
|
+
* RAM optimization: gunakan Map untuk handlers, weakly referenced jika possible
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import type { WAEventMap } from '../types/index.js';
|
|
9
|
+
export declare class WAEventEmitter extends EventEmitter {
|
|
10
|
+
/**
|
|
11
|
+
* Listen untuk specific event
|
|
12
|
+
*/
|
|
13
|
+
on<K extends keyof WAEventMap>(event: K, listener: (payload: WAEventMap[K]) => void): this;
|
|
14
|
+
/**
|
|
15
|
+
* Listen once
|
|
16
|
+
*/
|
|
17
|
+
once<K extends keyof WAEventMap>(event: K, listener: (payload: WAEventMap[K]) => void): this;
|
|
18
|
+
/**
|
|
19
|
+
* Listen dengan off support
|
|
20
|
+
*/
|
|
21
|
+
addListener<K extends keyof WAEventMap>(event: K, listener: (payload: WAEventMap[K]) => void): this;
|
|
22
|
+
/**
|
|
23
|
+
* Emit event ke all listeners
|
|
24
|
+
*/
|
|
25
|
+
emit<K extends keyof WAEventMap>(event: K, payload: WAEventMap[K]): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Remove listener
|
|
28
|
+
*/
|
|
29
|
+
off<K extends keyof WAEventMap>(event: K, listener: (payload: WAEventMap[K]) => void): this;
|
|
30
|
+
/**
|
|
31
|
+
* Wait for event dengan timeout
|
|
32
|
+
*/
|
|
33
|
+
waitFor<K extends keyof WAEventMap>(event: K, timeoutMs?: number): Promise<WAEventMap[K]>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Strict event emitter - hanya registered events yang di-allow
|
|
37
|
+
* Berguna untuk catching typos dalam event names
|
|
38
|
+
*/
|
|
39
|
+
export declare class StrictEventEmitter extends WAEventEmitter {
|
|
40
|
+
private knownEvents;
|
|
41
|
+
constructor(events: (keyof WAEventMap)[]);
|
|
42
|
+
emit<K extends keyof WAEventMap>(event: K, payload: WAEventMap[K]): boolean;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/events/emitter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,cAAe,SAAQ,YAAY;IAC9C;;OAEG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAI1F;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAI5F;;OAEG;IACH,WAAW,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAInG;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO;IAI3E;;OAEG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAI3F;;OAEG;IACG,OAAO,CAAC,CAAC,SAAS,MAAM,UAAU,EACtC,KAAK,EAAE,CAAC,EACR,SAAS,GAAE,MAAc,GACxB,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;CAe1B;AAED;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;IACpD,OAAO,CAAC,WAAW,CAAc;gBAErB,MAAM,EAAE,CAAC,MAAM,UAAU,CAAC,EAAE;IAKxC,IAAI,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO;CAM5E"}
|