whalibmob 5.29.3 → 5.29.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -0
- package/index.d.ts +11 -1
- package/lib/DeviceConfig.js +8 -1
- package/lib/Registration.js +132 -12
- package/lib/Store.js +12 -0
- package/lib/constants.js +15 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5507,6 +5507,30 @@ These variables override individual fields on top of the selected profile:
|
|
|
5507
5507
|
| `WA_DEVICE_OS_VERSION` | OS version string (e.g. `14`) |
|
|
5508
5508
|
| `WA_DEVICE_BUILD` | Build fingerprint (e.g. `UP1A.231005.007`) |
|
|
5509
5509
|
| `WA_DEVICE_MODEL_ID` | Model ID slug (e.g. `samsung-sm-s928b`) |
|
|
5510
|
+
| `WA_DEVICE_RAM` | Usable RAM in GiB, as Android reports it (e.g. `7.53`). Each named profile carries its own; set this only for a different memory variant of the same model. |
|
|
5511
|
+
|
|
5512
|
+
### Declaring your SIM
|
|
5513
|
+
|
|
5514
|
+
Registration sends `sim_mcc` / `sim_mnc` to say which network the SIM belongs
|
|
5515
|
+
to. The built-in table can only name **one operator per country** — Romania is
|
|
5516
|
+
always Orange, Brazil always Vivo — and it cannot do better, because number
|
|
5517
|
+
portability broke the prefix→operator link years ago. Guessing from the number
|
|
5518
|
+
would be wrong more often than the table is.
|
|
5519
|
+
|
|
5520
|
+
So say which SIM is in the phone:
|
|
5521
|
+
|
|
5522
|
+
```js
|
|
5523
|
+
const store = createNewStore('40712345678', { simMcc: '226', simMnc: '01' })
|
|
5524
|
+
```
|
|
5525
|
+
|
|
5526
|
+
| Variable | Description |
|
|
5527
|
+
|---|---|
|
|
5528
|
+
| `WA_SIM_MCC` | Mobile country code of the SIM (e.g. `226`) |
|
|
5529
|
+
| `WA_SIM_MNC` | Mobile network code. **Width matters** — `10` and `010` are different networks to the server, so write it exactly as your operator does. |
|
|
5530
|
+
|
|
5531
|
+
Either half can be given on its own; the other keeps the table's value, and the
|
|
5532
|
+
country's language and locale are unaffected either way. Leave both unset and
|
|
5533
|
+
nothing changes from before.
|
|
5510
5534
|
|
|
5511
5535
|
### Version & Token Overrides
|
|
5512
5536
|
|
|
@@ -5691,6 +5715,24 @@ registered, no code is requested, and the session is never written to.
|
|
|
5691
5715
|
the problem.** The difference is then in what the CLI reads and this tool does
|
|
5692
5716
|
not — `WA_VERSION`, from `.env`. Go back to the top of this section.
|
|
5693
5717
|
|
|
5718
|
+
## Support this project
|
|
5719
|
+
|
|
5720
|
+
If whalibmob saves you time, you can support its development.
|
|
5721
|
+
|
|
5722
|
+
**USDT — TRC-20 (Tron network only)**
|
|
5723
|
+
|
|
5724
|
+
```
|
|
5725
|
+
TNxxWvAc5m5YS89uz5uSrbXC9EKPuS27aP
|
|
5726
|
+
```
|
|
5727
|
+
|
|
5728
|
+
> [!WARNING]
|
|
5729
|
+
> This address is **TRC-20 on the Tron network**. Send **only USDT on TRC-20** to
|
|
5730
|
+
> it. USDT sent on any other network — ERC-20 (Ethereum), BEP-20 (BSC), Polygon,
|
|
5731
|
+
> or anything else — will be **lost and cannot be recovered**. Always double-check
|
|
5732
|
+
> the network in your wallet before sending, and copy the address in full.
|
|
5733
|
+
|
|
5734
|
+
The **Sponsor** button at the top of the repository leads back here.
|
|
5735
|
+
|
|
5694
5736
|
## License
|
|
5695
5737
|
|
|
5696
5738
|
MIT
|
package/index.d.ts
CHANGED
|
@@ -1228,7 +1228,17 @@ export declare function fetchWaWebVersion(): Promise<{ version: [number, number,
|
|
|
1228
1228
|
// Stores
|
|
1229
1229
|
// ────────────────────────────────────────────────────────────────────────────
|
|
1230
1230
|
|
|
1231
|
-
export declare function createNewStore(phoneNumber: string, opts?: {
|
|
1231
|
+
export declare function createNewStore(phoneNumber: string, opts?: {
|
|
1232
|
+
name?: string;
|
|
1233
|
+
/**
|
|
1234
|
+
* The MCC of the SIM actually in the phone. Without it the country table's
|
|
1235
|
+
* one-operator-per-country guess stands — number portability means the
|
|
1236
|
+
* number's prefix cannot tell you. Also settable as `WA_SIM_MCC`.
|
|
1237
|
+
*/
|
|
1238
|
+
simMcc?: string;
|
|
1239
|
+
/** The matching MNC. Width matters: `10` and `010` are different networks. */
|
|
1240
|
+
simMnc?: string;
|
|
1241
|
+
}): WhalibmobStore;
|
|
1232
1242
|
/** What the CLI uses for every new SMS session; prefer it over `createNewStore`. */
|
|
1233
1243
|
export declare function initAuthCreds(phoneNumber: string, opts?: { name?: string }): WhalibmobStore;
|
|
1234
1244
|
export declare function saveStore(store: WhalibmobStore, filePath: string): void;
|
package/lib/DeviceConfig.js
CHANGED
|
@@ -55,9 +55,13 @@ function getDeviceConfig() {
|
|
|
55
55
|
const profileKey = _normalise(process.env.WA_DEVICE || 'samsungs24ultra');
|
|
56
56
|
const found = _ANDROID_MAP[profileKey] || null;
|
|
57
57
|
if (found) {
|
|
58
|
-
|
|
58
|
+
const picked = Object.assign({}, found, business
|
|
59
59
|
? { business: true, platform: PLATFORM.ANDROID_BUSINESS }
|
|
60
60
|
: { business: false });
|
|
61
|
+
// A named profile carries the handset's own RAM; WA_DEVICE_RAM overrides
|
|
62
|
+
// it for someone running the same model in a different memory variant.
|
|
63
|
+
if (process.env.WA_DEVICE_RAM) picked.ram = process.env.WA_DEVICE_RAM;
|
|
64
|
+
return picked;
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
return {
|
|
@@ -69,6 +73,9 @@ function getDeviceConfig() {
|
|
|
69
73
|
osVersion: process.env.WA_DEVICE_OS_VERSION || '14',
|
|
70
74
|
osBuildNumber: process.env.WA_DEVICE_BUILD || 'UP1A.231005.007',
|
|
71
75
|
modelId: process.env.WA_DEVICE_MODEL_ID || 'SM-S928B',
|
|
76
|
+
// What the handset reports as usable RAM, in GiB. Registration sends it,
|
|
77
|
+
// and it has to belong to the handset beside it — see deviceRam().
|
|
78
|
+
ram: process.env.WA_DEVICE_RAM || '11.55',
|
|
72
79
|
deviceModelType: 2
|
|
73
80
|
};
|
|
74
81
|
}
|
package/lib/Registration.js
CHANGED
|
@@ -478,8 +478,32 @@ const COUNTRY_META = {
|
|
|
478
478
|
'998': { mcc: '434', mnc: '03', lg: 'ru', lc: 'UZ' }, // Uzbekistan (UzMobile)
|
|
479
479
|
};
|
|
480
480
|
|
|
481
|
-
|
|
482
|
-
|
|
481
|
+
// The carrier metadata for a country calling code.
|
|
482
|
+
//
|
|
483
|
+
// The table names one operator per country — Romania is always Orange, Brazil
|
|
484
|
+
// always Vivo — because that is the best a table keyed by calling code can do.
|
|
485
|
+
// It cannot be better: number portability means the prefix stopped naming the
|
|
486
|
+
// operator years ago, so guessing from the number would be wrong more often
|
|
487
|
+
// than the table is.
|
|
488
|
+
//
|
|
489
|
+
// So the caller can say instead. Whoever is registering knows which SIM is in
|
|
490
|
+
// the phone, and sim_mcc/sim_mnc are meant to describe that SIM; WA_SIM_MCC and
|
|
491
|
+
// WA_SIM_MNC (or `simMcc`/`simMnc` in the options) override the guess with the
|
|
492
|
+
// truth. The language and locale stay with the country either way.
|
|
493
|
+
//
|
|
494
|
+
// MNC keeps whatever width it is given: 226/10 and 226/010 are different
|
|
495
|
+
// networks to the server, and normalising them would break one of the two.
|
|
496
|
+
function getCountryMeta(cc, opts) {
|
|
497
|
+
const base = COUNTRY_META[cc] || { mcc: '000', mnc: '000', lg: 'en', lc: 'US' };
|
|
498
|
+
|
|
499
|
+
const mcc = (opts && opts.simMcc) || process.env.WA_SIM_MCC;
|
|
500
|
+
const mnc = (opts && opts.simMnc) || process.env.WA_SIM_MNC;
|
|
501
|
+
if (!mcc && !mnc) return base;
|
|
502
|
+
|
|
503
|
+
const out = Object.assign({}, base);
|
|
504
|
+
if (mcc) out.mcc = String(mcc).trim();
|
|
505
|
+
if (mnc) out.mnc = String(mnc).trim();
|
|
506
|
+
return out;
|
|
483
507
|
}
|
|
484
508
|
|
|
485
509
|
// ---------- Phone number parsing ----------
|
|
@@ -962,18 +986,38 @@ function tryLoadAndroidMaterial(device) {
|
|
|
962
986
|
* Silently ignoring WA_OS is how you end up watching an Android registration go
|
|
963
987
|
* out under an iOS User-Agent and not knowing why.
|
|
964
988
|
*/
|
|
989
|
+
// A session's device identity, frozen for the whole registration.
|
|
990
|
+
//
|
|
991
|
+
// createNewStore captures the device when the session is created and writes it
|
|
992
|
+
// to disk with everything else, so a session always arrives here already
|
|
993
|
+
// carrying one. From that point it is frozen: /exist, /code, /register and
|
|
994
|
+
// every retry read this same identity, and no request can describe one handset
|
|
995
|
+
// while a sibling request in the same flow describes another.
|
|
996
|
+
//
|
|
997
|
+
// The bug this closes: the gate here used to be `registered || codePending`, so
|
|
998
|
+
// the very first /code of a session ignored the stored device and re-read it
|
|
999
|
+
// from the environment. /exist had already gone out as the stored device — an
|
|
1000
|
+
// Android/Samsung, say, loaded from the session file — and /code then went out
|
|
1001
|
+
// as the environment default (iOS/iPhone). One number, two phones, in one flow.
|
|
1002
|
+
// That is precisely the shape a "download the official app" block screen looks
|
|
1003
|
+
// for, and it was reproducible from the logs. See
|
|
1004
|
+
// test/registration-device-consistency.test.js.
|
|
1005
|
+
//
|
|
1006
|
+
// WA_OS / WA_BUSINESS therefore choose the device only for a session that does
|
|
1007
|
+
// not have one yet — which in practice means never, since createNewStore always
|
|
1008
|
+
// sets it. To change the platform of an existing session, start it over: delete
|
|
1009
|
+
// the session file, and the next createNewStore picks up the current WA_OS.
|
|
965
1010
|
function deviceForRegistration(store, opts) {
|
|
966
1011
|
const env = getDeviceConfig();
|
|
967
1012
|
const stored = store && store.device;
|
|
968
|
-
|
|
969
|
-
if (!settled || !stored) return env;
|
|
1013
|
+
if (!stored || !stored.os) return env;
|
|
970
1014
|
|
|
971
1015
|
const say = (opts && opts.onProgress) || (m => _whaDbg('[DBG] REG ' + m));
|
|
972
1016
|
|
|
973
1017
|
if (stored.os !== env.os) {
|
|
974
1018
|
say('note: this session was started as ' + stored.os + ', so it stays ' + stored.os +
|
|
975
|
-
' — WA_OS=' + env.os + ' does not apply to a number that
|
|
976
|
-
'
|
|
1019
|
+
' — WA_OS=' + env.os + ' does not apply to a number that already has a ' +
|
|
1020
|
+
'device. Delete the session file to start it over as ' + env.os + '.');
|
|
977
1021
|
}
|
|
978
1022
|
|
|
979
1023
|
// The same rule for the variant: an account is created as Business or as
|
|
@@ -983,13 +1027,36 @@ function deviceForRegistration(store, opts) {
|
|
|
983
1027
|
if (!!stored.business !== !!env.business) {
|
|
984
1028
|
say('note: this session was started as ' + (stored.business ? 'Business' : 'consumer') +
|
|
985
1029
|
', so it stays that — WA_BUSINESS=' + (env.business ? '1' : '0') +
|
|
986
|
-
' does not apply to a number that
|
|
1030
|
+
' does not apply to a number that already has a device. ' +
|
|
987
1031
|
'Delete the session file to start it over.');
|
|
988
1032
|
}
|
|
989
1033
|
|
|
990
1034
|
return stored;
|
|
991
1035
|
}
|
|
992
1036
|
|
|
1037
|
+
// The device identity a request is about to go out with, logged so /exist and
|
|
1038
|
+
// /code can be compared side by side. Gated behind the debug channel — it costs
|
|
1039
|
+
// nothing when debug is off, and when a registration misbehaves it is the first
|
|
1040
|
+
// thing worth seeing. The User-Agent is built the same way the real request
|
|
1041
|
+
// builds it, so what this prints is what actually goes on the wire.
|
|
1042
|
+
function logDeviceIdentity(tag, store, waVersion) {
|
|
1043
|
+
const stored = store && store.device;
|
|
1044
|
+
const d = stored || getDeviceConfig();
|
|
1045
|
+
const ver = waVersion || (store && store.version) || '';
|
|
1046
|
+
let ua = '';
|
|
1047
|
+
try { ua = registrationHeaders(d, ver)['User-Agent']; } catch (_) {}
|
|
1048
|
+
_whaDbg('[DBG] DEVICE_IDENTITY ' + tag +
|
|
1049
|
+
' os=' + d.os +
|
|
1050
|
+
' osVersion=' + d.osVersion +
|
|
1051
|
+
' manufacturer=' + (d.manufacturer || '-') +
|
|
1052
|
+
' model=' + (d.model || d.modelId || '-') +
|
|
1053
|
+
' modelId=' + (d.modelId || '-') +
|
|
1054
|
+
' business=' + !!d.business +
|
|
1055
|
+
' waVersion=' + (ver || '-') +
|
|
1056
|
+
' source=' + (stored ? 'store.device (frozen)' : 'getDeviceConfig() (env/default)') +
|
|
1057
|
+
' ua="' + ua + '"');
|
|
1058
|
+
}
|
|
1059
|
+
|
|
993
1060
|
/**
|
|
994
1061
|
* Have the Android token material ready, fetching the APK if it is not.
|
|
995
1062
|
*
|
|
@@ -1201,6 +1268,57 @@ function waitHint(response, method) {
|
|
|
1201
1268
|
return retry > 0 ? retry : null;
|
|
1202
1269
|
}
|
|
1203
1270
|
|
|
1271
|
+
// ---------- device_ram ----------
|
|
1272
|
+
//
|
|
1273
|
+
// What the handset reports as usable RAM, in GiB, from
|
|
1274
|
+
// ActivityManager.MemoryInfo.totalMem — which is always below the nominal
|
|
1275
|
+
// figure on the box, because the kernel, the GPU and the secure world reserve a
|
|
1276
|
+
// slice before Android ever sees it. A 12 GB phone reports around 11.5.
|
|
1277
|
+
//
|
|
1278
|
+
// This was the constant 3.57 on every request, while the same payload declared
|
|
1279
|
+
// a Galaxy S24 Ultra beside it. There is no such handset: the S24 Ultra ships
|
|
1280
|
+
// with 12 GB and no variant of it has ever had 3.57. Two fields of one request
|
|
1281
|
+
// describing two different phones is not a fingerprint worth defending — it is
|
|
1282
|
+
// simply wrong, in the way a wrong `os_version` would be. It now comes off the
|
|
1283
|
+
// declared profile, so whichever handset the caller says they are on, the
|
|
1284
|
+
// memory belongs to it.
|
|
1285
|
+
const DEFAULT_DEVICE_RAM = '5.62';
|
|
1286
|
+
|
|
1287
|
+
function deviceRam(device) {
|
|
1288
|
+
const ram = device && device.ram;
|
|
1289
|
+
if (ram == null) return DEFAULT_DEVICE_RAM;
|
|
1290
|
+
const n = Number(ram);
|
|
1291
|
+
// Two decimals, the way the client formats it.
|
|
1292
|
+
return Number.isFinite(n) && n > 0 ? n.toFixed(2) : DEFAULT_DEVICE_RAM;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
// ---------- pid ----------
|
|
1296
|
+
//
|
|
1297
|
+
// The process id of the app making the request.
|
|
1298
|
+
//
|
|
1299
|
+
// This sent `process.pid` — the Node process. Inside a container that is 1, and
|
|
1300
|
+
// pid 1 on Android is `init`; no application process is ever 1. Elsewhere it is
|
|
1301
|
+
// whatever the host happened to hand out, which is as likely to be 7 as 24000.
|
|
1302
|
+
//
|
|
1303
|
+
// Android hands out pids from a counter that starts near 300 and wraps at
|
|
1304
|
+
// /proc/sys/kernel/pid_max, 32768 by default, so an app launched on a phone
|
|
1305
|
+
// that has been up any length of time lands well inside that range. One is
|
|
1306
|
+
// derived per store here, from the same identity material everything else in
|
|
1307
|
+
// the payload comes from — deterministic on purpose, because /exist, /code and
|
|
1308
|
+
// /register are three requests from one running app and a process does not
|
|
1309
|
+
// change its pid between them. Restoring a saved session keeps the pid it had,
|
|
1310
|
+
// for the same reason.
|
|
1311
|
+
function getAppPid(store) {
|
|
1312
|
+
if (store._appPid) return store._appPid;
|
|
1313
|
+
const seed = (store.identityId && Buffer.isBuffer(store.identityId))
|
|
1314
|
+
? store.identityId
|
|
1315
|
+
: Buffer.from(String(store.phoneNumber || ''), 'utf8');
|
|
1316
|
+
const h = crypto.createHash('sha256').update(seed).update('pid').digest();
|
|
1317
|
+
// 1024..32767 — clear of the kernel and early-boot range, inside pid_max.
|
|
1318
|
+
store._appPid = String(1024 + (h.readUInt32BE(0) % (32768 - 1024)));
|
|
1319
|
+
return store._appPid;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1204
1322
|
function buildClientMetrics(attempt) {
|
|
1205
1323
|
const json = '{"attempts":' + (attempt || 1)
|
|
1206
1324
|
+ ',"app_campaign_download_source":"google-play|unknown"'
|
|
@@ -1250,9 +1368,9 @@ function getRequestVerificationCodeParameters(store, method, meta, device, attem
|
|
|
1250
1368
|
'advertising_id', store.advertisingId || '',
|
|
1251
1369
|
'hasinrc', '1',
|
|
1252
1370
|
'roaming_type', '0',
|
|
1253
|
-
'device_ram',
|
|
1371
|
+
'device_ram', deviceRam(device),
|
|
1254
1372
|
'education_screen_displayed', 'true',
|
|
1255
|
-
'pid',
|
|
1373
|
+
'pid', getAppPid(store),
|
|
1256
1374
|
'cellular_strength', '5',
|
|
1257
1375
|
'backup_token', store.backupToken ? toUrlHex(store.backupToken) : '',
|
|
1258
1376
|
'tos_version', '5',
|
|
@@ -1354,7 +1472,7 @@ function buildVerifiedNameCertificate(store, device) {
|
|
|
1354
1472
|
|
|
1355
1473
|
async function buildPayload(store, waVersion, useToken, extraPairs) {
|
|
1356
1474
|
const { cc, national } = parsePhone(store.phoneNumber);
|
|
1357
|
-
const meta = getCountryMeta(cc);
|
|
1475
|
+
const meta = getCountryMeta(cc, store);
|
|
1358
1476
|
const device = store.device || getDeviceConfig();
|
|
1359
1477
|
const token = useToken ? computeToken(waVersion, national, device) : null;
|
|
1360
1478
|
// Android formats fdid lowercase, iOS uppercase (matches the native clients).
|
|
@@ -1826,7 +1944,7 @@ async function checkNumberStatus(phoneNumber) {
|
|
|
1826
1944
|
const store = createNewStore(phoneNumber);
|
|
1827
1945
|
const waVersion = await fetchWaVersion(_device);
|
|
1828
1946
|
const { cc } = parsePhone(phoneNumber);
|
|
1829
|
-
const meta = getCountryMeta(cc);
|
|
1947
|
+
const meta = getCountryMeta(cc, store);
|
|
1830
1948
|
|
|
1831
1949
|
function hasBlock(r) {
|
|
1832
1950
|
return r && !!r.custom_block_screen;
|
|
@@ -1908,6 +2026,7 @@ async function assertRegistrationKeys(store, waVersion) {
|
|
|
1908
2026
|
|
|
1909
2027
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
1910
2028
|
try {
|
|
2029
|
+
logDeviceIdentity('before /exist', store, waVersion);
|
|
1911
2030
|
const result = await sendRequest('/exist', store, waVersion, false, null);
|
|
1912
2031
|
// reason === 'incorrect' → keys not found → fresh
|
|
1913
2032
|
if (result && result.reason === 'incorrect') {
|
|
@@ -1988,7 +2107,7 @@ async function requestSmsCode(store, method, opts) {
|
|
|
1988
2107
|
|
|
1989
2108
|
// Derive real MCC/MNC from the phone number being registered.
|
|
1990
2109
|
const { cc: _regCc } = parsePhone(store.phoneNumber);
|
|
1991
|
-
const _regMeta = getCountryMeta(_regCc);
|
|
2110
|
+
const _regMeta = getCountryMeta(_regCc, store);
|
|
1992
2111
|
|
|
1993
2112
|
async function _tryMethod(m) {
|
|
1994
2113
|
// Retry loop:
|
|
@@ -2012,6 +2131,7 @@ async function requestSmsCode(store, method, opts) {
|
|
|
2012
2131
|
const verifyScreen = currentVerifyScreen(store);
|
|
2013
2132
|
await sendFunnelLog(store, waVersion, verifyScreen, 'request_code', 'request_code_attempt');
|
|
2014
2133
|
|
|
2134
|
+
logDeviceIdentity('before /code', store, waVersion);
|
|
2015
2135
|
const result = await sendRequest('/code', store, waVersion, true, extra);
|
|
2016
2136
|
|
|
2017
2137
|
const status = result.status;
|
package/lib/Store.js
CHANGED
|
@@ -113,6 +113,12 @@ function createNewStore(phoneNumber, opts) {
|
|
|
113
113
|
registered: false,
|
|
114
114
|
codePending: false, // true after /code request, cleared on successful /register
|
|
115
115
|
name: normalizePushName(opts.name) || 'User',
|
|
116
|
+
// Which SIM is actually in the phone. The country table can only guess one
|
|
117
|
+
// operator per calling code — number portability broke the prefix→operator
|
|
118
|
+
// link long ago — so whoever is registering can name theirs instead. Null
|
|
119
|
+
// leaves the table's guess in place. See getCountryMeta in Registration.js.
|
|
120
|
+
simMcc: opts.simMcc ? String(opts.simMcc).trim() : null,
|
|
121
|
+
simMnc: opts.simMnc ? String(opts.simMnc).trim() : null,
|
|
116
122
|
version,
|
|
117
123
|
device,
|
|
118
124
|
// ADVSignedDeviceIdentity bytes received from server <success> node.
|
|
@@ -194,6 +200,8 @@ function storeToJson(store) {
|
|
|
194
200
|
advertisingId: store.advertisingId || null,
|
|
195
201
|
backupToken: store.backupToken ? store.backupToken.toString('base64') : null,
|
|
196
202
|
registered: !!store.registered,
|
|
203
|
+
simMcc: store.simMcc || null,
|
|
204
|
+
simMnc: store.simMnc || null,
|
|
197
205
|
codePending: store.codePending || false,
|
|
198
206
|
// Which delivery method the pending code actually went out by. The two
|
|
199
207
|
// registration steps are normally separate commands, so the confirmation
|
|
@@ -246,6 +254,10 @@ function storeFromJson(obj) {
|
|
|
246
254
|
advertisingId: obj.advertisingId || uuidv4(),
|
|
247
255
|
backupToken: obj.backupToken ? Buffer.from(obj.backupToken, 'base64') : crypto.randomBytes(20),
|
|
248
256
|
registered: !!obj.registered,
|
|
257
|
+
// Null on stores written before the SIM could be declared, which simply
|
|
258
|
+
// means the country table's guess stands.
|
|
259
|
+
simMcc: obj.simMcc || null,
|
|
260
|
+
simMnc: obj.simMnc || null,
|
|
249
261
|
codePending: obj.codePending || false,
|
|
250
262
|
codeMethod: obj.codeMethod || null,
|
|
251
263
|
// Absent on stores written before push tokens existed; null simply means
|
package/lib/constants.js
CHANGED
|
@@ -169,91 +169,91 @@ const ANDROID_DEVICE_PROFILES = {
|
|
|
169
169
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
170
170
|
model: 'Samsung Galaxy S24 Ultra', manufacturer: 'Samsung',
|
|
171
171
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
172
|
-
modelId: 'SM-S928B', deviceModelType: 2
|
|
172
|
+
modelId: 'SM-S928B', deviceModelType: 2, ram: '11.55'
|
|
173
173
|
},
|
|
174
174
|
'samsung-s24': {
|
|
175
175
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
176
176
|
model: 'Samsung Galaxy S24', manufacturer: 'Samsung',
|
|
177
177
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
178
|
-
modelId: 'SM-S921B', deviceModelType: 2
|
|
178
|
+
modelId: 'SM-S921B', deviceModelType: 2, ram: '7.63'
|
|
179
179
|
},
|
|
180
180
|
'samsung-s23': {
|
|
181
181
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
182
182
|
model: 'Samsung Galaxy S23', manufacturer: 'Samsung',
|
|
183
183
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
184
|
-
modelId: 'SM-S911B', deviceModelType: 2
|
|
184
|
+
modelId: 'SM-S911B', deviceModelType: 2, ram: '7.63'
|
|
185
185
|
},
|
|
186
186
|
'samsung-s23-ultra': {
|
|
187
187
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
188
188
|
model: 'Samsung Galaxy S23 Ultra', manufacturer: 'Samsung',
|
|
189
189
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
190
|
-
modelId: 'SM-S918B', deviceModelType: 2
|
|
190
|
+
modelId: 'SM-S918B', deviceModelType: 2, ram: '11.55'
|
|
191
191
|
},
|
|
192
192
|
'samsung-a55': {
|
|
193
193
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
194
194
|
model: 'Samsung Galaxy A55', manufacturer: 'Samsung',
|
|
195
195
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
196
|
-
modelId: 'SM-A556B', deviceModelType: 1
|
|
196
|
+
modelId: 'SM-A556B', deviceModelType: 1, ram: '7.44'
|
|
197
197
|
},
|
|
198
198
|
'pixel8pro': {
|
|
199
199
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
200
200
|
model: 'Pixel 8 Pro', manufacturer: 'Google',
|
|
201
201
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
202
|
-
modelId: 'Pixel 8 Pro', deviceModelType: 2
|
|
202
|
+
modelId: 'Pixel 8 Pro', deviceModelType: 2, ram: '11.44'
|
|
203
203
|
},
|
|
204
204
|
'pixel8': {
|
|
205
205
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
206
206
|
model: 'Pixel 8', manufacturer: 'Google',
|
|
207
207
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
208
|
-
modelId: 'Pixel 8', deviceModelType: 2
|
|
208
|
+
modelId: 'Pixel 8', deviceModelType: 2, ram: '7.53'
|
|
209
209
|
},
|
|
210
210
|
'pixel7': {
|
|
211
211
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
212
212
|
model: 'Pixel 7', manufacturer: 'Google',
|
|
213
213
|
osVersion: '14', osBuildNumber: 'TP1A.221005.002',
|
|
214
|
-
modelId: 'Pixel 7', deviceModelType: 2
|
|
214
|
+
modelId: 'Pixel 7', deviceModelType: 2, ram: '7.53'
|
|
215
215
|
},
|
|
216
216
|
'pixel7a': {
|
|
217
217
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
218
218
|
model: 'Pixel 7a', manufacturer: 'Google',
|
|
219
219
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
220
|
-
modelId: 'Pixel 7a', deviceModelType: 1
|
|
220
|
+
modelId: 'Pixel 7a', deviceModelType: 1, ram: '7.44'
|
|
221
221
|
},
|
|
222
222
|
'xiaomi14': {
|
|
223
223
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
224
224
|
model: 'Xiaomi 14', manufacturer: 'Xiaomi',
|
|
225
225
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
226
|
-
modelId: '23127PN0CG', deviceModelType: 2
|
|
226
|
+
modelId: '23127PN0CG', deviceModelType: 2, ram: '11.36'
|
|
227
227
|
},
|
|
228
228
|
'xiaomi13': {
|
|
229
229
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
230
230
|
model: 'Xiaomi 13', manufacturer: 'Xiaomi',
|
|
231
231
|
osVersion: '13', osBuildNumber: 'TQ3A.230901.001',
|
|
232
|
-
modelId: '2211133G', deviceModelType: 2
|
|
232
|
+
modelId: '2211133G', deviceModelType: 2, ram: '7.51'
|
|
233
233
|
},
|
|
234
234
|
'oneplus12': {
|
|
235
235
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
236
236
|
model: 'OnePlus 12', manufacturer: 'OnePlus',
|
|
237
237
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
238
|
-
modelId: 'CPH2573', deviceModelType: 2
|
|
238
|
+
modelId: 'CPH2573', deviceModelType: 2, ram: '11.48'
|
|
239
239
|
},
|
|
240
240
|
'oneplus11': {
|
|
241
241
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
242
242
|
model: 'OnePlus 11', manufacturer: 'OnePlus',
|
|
243
243
|
osVersion: '13', osBuildNumber: 'TQ3A.230901.001',
|
|
244
|
-
modelId: 'CPH2449', deviceModelType: 2
|
|
244
|
+
modelId: 'CPH2449', deviceModelType: 2, ram: '15.32'
|
|
245
245
|
},
|
|
246
246
|
'oppo-find-x7': {
|
|
247
247
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
248
248
|
model: 'OPPO Find X7', manufacturer: 'OPPO',
|
|
249
249
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
250
|
-
modelId: 'CPH2599', deviceModelType: 2
|
|
250
|
+
modelId: 'CPH2599', deviceModelType: 2, ram: '11.40'
|
|
251
251
|
},
|
|
252
252
|
'realme-gt5': {
|
|
253
253
|
os: 'android', platform: PLATFORM.ANDROID,
|
|
254
254
|
model: 'realme GT 5 Pro', manufacturer: 'realme',
|
|
255
255
|
osVersion: '14', osBuildNumber: 'UP1A.231005.007',
|
|
256
|
-
modelId: 'RMX3888', deviceModelType: 2
|
|
256
|
+
modelId: 'RMX3888', deviceModelType: 2, ram: '15.28'
|
|
257
257
|
}
|
|
258
258
|
};
|
|
259
259
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "whalibmob",
|
|
3
|
-
"version": "5.29.
|
|
3
|
+
"version": "5.29.5",
|
|
4
4
|
"description": "Node.js library for WhatsApp — register a number over SMS, or link as a companion by QR. Signal E2E encryption, media, groups, channels.",
|
|
5
5
|
"author": "Kunboruto20",
|
|
6
6
|
"main": "index.js",
|