nkx-fca 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.
Files changed (116) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/COOKIE_LOGIN.md +208 -0
  3. package/LICENSE +3 -0
  4. package/README.md +504 -0
  5. package/examples/login-with-cookies.js +102 -0
  6. package/examples/ping.js +1 -0
  7. package/index.js +2 -0
  8. package/package.json +90 -0
  9. package/src/apis/addExternalModule.js +24 -0
  10. package/src/apis/addUserToGroup.js +108 -0
  11. package/src/apis/changeAdminStatus.js +148 -0
  12. package/src/apis/changeArchivedStatus.js +61 -0
  13. package/src/apis/changeAvatar.js +103 -0
  14. package/src/apis/changeBio.js +69 -0
  15. package/src/apis/changeBlockedStatus.js +54 -0
  16. package/src/apis/changeGroupImage.js +136 -0
  17. package/src/apis/changeThreadColor.js +116 -0
  18. package/src/apis/changeThreadEmoji.js +53 -0
  19. package/src/apis/comment.js +207 -0
  20. package/src/apis/createAITheme.js +129 -0
  21. package/src/apis/createNewGroup.js +79 -0
  22. package/src/apis/createPoll.js +73 -0
  23. package/src/apis/deleteMessage.js +44 -0
  24. package/src/apis/deleteThread.js +52 -0
  25. package/src/apis/e2ee.js +17 -0
  26. package/src/apis/editMessage.js +70 -0
  27. package/src/apis/emoji.js +124 -0
  28. package/src/apis/fetchThemeData.js +82 -0
  29. package/src/apis/follow.js +81 -0
  30. package/src/apis/forwardMessage.js +52 -0
  31. package/src/apis/friend.js +243 -0
  32. package/src/apis/gcmember.js +122 -0
  33. package/src/apis/gcname.js +123 -0
  34. package/src/apis/gcrule.js +119 -0
  35. package/src/apis/getAccess.js +111 -0
  36. package/src/apis/getBotInfo.js +88 -0
  37. package/src/apis/getBotInitialData.js +43 -0
  38. package/src/apis/getFriendsList.js +79 -0
  39. package/src/apis/getMessage.js +423 -0
  40. package/src/apis/getTheme.js +95 -0
  41. package/src/apis/getThemeInfo.js +116 -0
  42. package/src/apis/getThreadHistory.js +239 -0
  43. package/src/apis/getThreadInfo.js +267 -0
  44. package/src/apis/getThreadList.js +232 -0
  45. package/src/apis/getThreadPictures.js +58 -0
  46. package/src/apis/getUserID.js +120 -0
  47. package/src/apis/getUserInfo.js +513 -0
  48. package/src/apis/getUserInfoV2.js +146 -0
  49. package/src/apis/handleMessageRequest.js +50 -0
  50. package/src/apis/httpGet.js +63 -0
  51. package/src/apis/httpPost.js +89 -0
  52. package/src/apis/httpPostFormData.js +69 -0
  53. package/src/apis/listenMqtt.js +961 -0
  54. package/src/apis/listenSpeed.js +179 -0
  55. package/src/apis/logout.js +63 -0
  56. package/src/apis/markAsDelivered.js +47 -0
  57. package/src/apis/markAsRead.js +95 -0
  58. package/src/apis/markAsReadAll.js +40 -0
  59. package/src/apis/markAsSeen.js +70 -0
  60. package/src/apis/mqttDeltaValue.js +278 -0
  61. package/src/apis/muteThread.js +45 -0
  62. package/src/apis/nickname.js +132 -0
  63. package/src/apis/notes.js +163 -0
  64. package/src/apis/pinMessage.js +150 -0
  65. package/src/apis/produceMetaTheme.js +180 -0
  66. package/src/apis/realtime.js +182 -0
  67. package/src/apis/removeUserFromGroup.js +118 -0
  68. package/src/apis/resolvePhotoUrl.js +58 -0
  69. package/src/apis/searchForThread.js +154 -0
  70. package/src/apis/sendMessage.js +359 -0
  71. package/src/apis/sendMessageMqtt.js +249 -0
  72. package/src/apis/sendTypingIndicator.js +40 -0
  73. package/src/apis/setMessageReaction.js +27 -0
  74. package/src/apis/setMessageReactionMqtt.js +61 -0
  75. package/src/apis/setThreadTheme.js +260 -0
  76. package/src/apis/setThreadThemeMqtt.js +94 -0
  77. package/src/apis/share.js +107 -0
  78. package/src/apis/shareContact.js +66 -0
  79. package/src/apis/stickers.js +257 -0
  80. package/src/apis/story.js +181 -0
  81. package/src/apis/theme.js +233 -0
  82. package/src/apis/unfriend.js +47 -0
  83. package/src/apis/unsendMessage.js +17 -0
  84. package/src/database/appStateBackup.js +255 -0
  85. package/src/database/models/index.js +56 -0
  86. package/src/database/models/thread.js +31 -0
  87. package/src/database/models/user.js +32 -0
  88. package/src/database/threadData.js +104 -0
  89. package/src/database/userData.js +102 -0
  90. package/src/engine/client.js +86 -0
  91. package/src/engine/models/buildAPI.js +113 -0
  92. package/src/engine/models/loginHelper.js +480 -0
  93. package/src/engine/models/setOptions.js +88 -0
  94. package/src/security/e2ee.js +190 -0
  95. package/src/types/index.d.ts +498 -0
  96. package/src/utils/antiSuspension.js +559 -0
  97. package/src/utils/auth-helpers.js +149 -0
  98. package/src/utils/autoReLogin.js +278 -0
  99. package/src/utils/axios.js +368 -0
  100. package/src/utils/cache.js +54 -0
  101. package/src/utils/clients.js +279 -0
  102. package/src/utils/constants.js +409 -0
  103. package/src/utils/formatters/data/formatAttachment.js +370 -0
  104. package/src/utils/formatters/data/formatDelta.js +109 -0
  105. package/src/utils/formatters/index.js +159 -0
  106. package/src/utils/formatters/value/formatCookie.js +91 -0
  107. package/src/utils/formatters/value/formatDate.js +36 -0
  108. package/src/utils/formatters/value/formatID.js +16 -0
  109. package/src/utils/formatters.js +1369 -0
  110. package/src/utils/headers.js +235 -0
  111. package/src/utils/index.js +152 -0
  112. package/src/utils/monitoring.js +333 -0
  113. package/src/utils/rateLimiter.js +260 -0
  114. package/src/utils/tokenRefresh.js +314 -0
  115. package/src/utils/user-agents.js +238 -0
  116. package/src/utils/validation.js +157 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,144 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## [1.2.0] - 2026-03-19
11
+
12
+ ### Fixed
13
+
14
+ **Token Refresh — Concurrency & Reliability**
15
+ - `TokenRefreshManager.refreshTokens` was not concurrency-safe: the 10-hour scheduled refresh, 2-hour health-check-triggered refresh, and `getSeqID` emergency refresh could all fire simultaneously, sending a burst of full homepage requests to Facebook and writing half-updated tokens (`fb_dtsg`, `lsd`, `ttstamp`, `jazoest`, `__rev`) to `ctx` mid-flight. Fixed by making `refreshTokens` a deduplication wrapper: all concurrent callers share the same in-flight Promise and receive the same result. Only one HTTP round-trip is ever issued at a time.
16
+ - Internal retry logic was ordered incorrectly: `failureCount >= MAX_FAILURES` was checked *before* exhausting internal per-call retries, so a single transient network error at the wrong moment immediately invoked `onSessionExpiry` (triggering a full re-login) without attempting the built-in 3-retry backoff. Retries now always run first; `onSessionExpiry` is only called after all retries are genuinely exhausted.
17
+
18
+ **Auto Re-Login — Recovery After Outages**
19
+ - The 15-minute recovery timer that resets `retryCount` after auto-relogin exhausts its 3 attempts now also calls `api.tokenRefreshManager.resetFailureCount()`. Previously, `failureCount` remained pinned at `MAX_FAILURES`, so the next scheduled token-refresh cycle (10-hour or 2-hour health-check) would escalate to `onSessionExpiry` on the very first transient error with no internal retries — incorrectly triggering another re-login when a simple retry would have worked.
20
+ - `pendingRequests` queue — callers waiting for an in-progress re-login to complete had no timeout and would hang forever if `loginHelper` stopped responding. Each queued waiter now times out after 5 minutes and rejects with a clear error message.
21
+ - Warmup timer (`enableWarmup`) — the `setTimeout` handle was not stored, so `destroy()` could not cancel it. Stored as `this._warmupTimer`; cleared on both re-call and `destroy()`.
22
+
23
+ **Memory — Thread Type Cache**
24
+ - `ctx.threadTypeCache` in `sendMessage` was a plain object that grew without bound — one entry per unique thread ID for the entire lifetime of the process. Replaced with `ctx.cache` (the existing TTL-based `SimpleCache`): thread-type lookups now expire after 24 hours and failed lookups after 1 hour.
25
+
26
+ **Rate Limiter — Stuck Counter Protection**
27
+ - `checkRateLimit` contained a `while (activeRequests >= MAX)` loop with no exit condition — the only loop in the file without a safety break. An event-loop anomaly that prevented the `setTimeout` decrement from firing would have permanently blocked every subsequent request. Added a 60-second forced exit: after 600 × 100 ms iterations the counter is reset to a safe value and a warning is logged.
28
+
29
+ **MQTT API Fixes**
30
+ - `removeUserFromGroup`: on the success path the 30-second MQTT timeout was not cleared (`clearTimeout` was missing), leaving the timer alive in the event loop until it fired, checked the `responseHandled` flag, and did nothing. Added `clearTimeout` before the success callback.
31
+ - `listenMqtt`: orphaned `callback_Task` entries (MQTT tasks with no response) now expire after 5 minutes; the watchdog removes them and invokes their callbacks with a timeout error rather than leaking them for the process lifetime.
32
+ - `listenMqtt`: orphaned `shareContact` callback accumulation fixed — entries now carry an `addedAt` timestamp so the watchdog can age them out.
33
+
34
+ ---
35
+
36
+ ## [1.1.0] - 2026-03-16
37
+
38
+ ### Fixed
39
+
40
+ **MQTT Reliability**
41
+ - `close` handler now captures `wasConnected` before clearing `ctx._mqttConnected`, so the quick-close detection window is evaluated correctly instead of always being skipped
42
+ - Re-auth triggered by the quick-close threshold now `return`s immediately, preventing a duplicate reconnect from the normal backoff path racing against it
43
+ - `offline` event now schedules a backoff reconnect after ending the client — previously the bot would silently stay offline with no recovery
44
+ - Added `maxReconnectAttempts` cap (default 100): after hitting the cap the library pauses 10 minutes before resetting, preventing an indefinite 30 s retry loop that is a detectable bot pattern
45
+
46
+ **Session & Auth**
47
+ - `stopListening` now stops the token-refresh manager and session monitor — they were continuing to hit Facebook endpoints after the bot was asked to stop
48
+ - `api.isSessionValid` replaced the full homepage fetch (~400 kB) with a lightweight presence-ping endpoint, reducing bandwidth and detection surface
49
+ - `startSessionMonitoring(api)` moved to after `api.isSessionValid` is registered in `loginHelper`, so the health-check interval can actually invoke it (previously it was called 70 lines before `api.isSessionValid` existed)
50
+ - `setCredentials` now resets `retryCount = 0` on every fresh login, preventing 3 prior re-login failures from permanently locking out future re-logins for the process lifetime
51
+
52
+ **Core**
53
+ - Internal `listenMqtt` function now receives `emitAuthError` as a parameter at both call sites; previously both callers omitted it, causing a `ReferenceError` whenever an auth error arrived on the MQTT connection
54
+
55
+ ---
56
+
57
+ ## [1.0.0] - 2026-03-14
58
+
59
+ Initial public release of **nkx-fca** — a full rewrite/rebranding of the FCA-KEX engine.
60
+ Developed and maintained by [NeoKEX](https://github.com/NeoKEX).
61
+
62
+ ### Added
63
+
64
+ **Core**
65
+ - Login via `appState` cookie arrays (supports `name/value`, `key/value`, and cookie strings)
66
+ - Multi-persona support: `desktop` (Chrome/Edge) and `android/mobile` personas
67
+ - Real-time MQTT messaging with `listenMqtt` and `sendMessageMqtt`
68
+ - HTTP send with automatic MQTT fallback (`sendMessage`)
69
+ - MQTT auto-reconnect with exponential backoff and jitter
70
+ - MQTT watchdog timer to detect and recover from idle/stale connections
71
+ - `TokenRefreshManager` with randomized refresh intervals to avoid detectable periodicity
72
+ - `AutoReLogin` using refreshed AppState on session expiry
73
+ - AppState backup/restore to disk to survive crashes
74
+ - SQLite-backed thread and user data caching via Sequelize
75
+
76
+ **Anti-Suspension System**
77
+ - `AntiSuspension` class with circuit breaker — trips after repeated suspension signals
78
+ - Expanded suspension signal detection: 60+ patterns covering checkpoints, spam flags, session expiry, rate limits, policy violations, identity verification, and more
79
+ - Adaptive per-thread message delay that scales with session volume
80
+ - Hourly and daily volume limits with automatic warning pauses
81
+ - `checkVolumeLimit()` called before every `sendMessage` and `sendMessageMqtt` send
82
+ - Warmup mode — reduced hourly limit for fresh sessions
83
+ - Session fingerprint locking: User-Agent, Sec-Ch-Ua, locale, timezone locked per session
84
+ - `safeRetry()` with suspension-aware exponential backoff
85
+ - `batchOperations()` for safe, sequential multi-send workflows
86
+ - MQTT Sec-Ch-Ua header updated to Chrome 136 (matching default User-Agent)
87
+ - PostSafe guard on HTTP post to detect auth failures in real-time
88
+
89
+ **API Methods**
90
+ - `api.sendMessage(msg, threadID)` — HTTP send with MQTT fallback
91
+ - `api.sendMessageMqtt(msg, threadID)` — MQTT send
92
+ - `api.listenMqtt(callback)` — real-time event listener
93
+ - `api.editMessage(text, messageID)` — in-place message edit
94
+ - `api.unsendMessage(messageID, threadID)` — retract a message
95
+ - `api.forwardMessage(messageID, threadID)` — forward a message
96
+ - `api.deleteMessage(messageIDs)` — delete locally
97
+ - `api.setMessageReaction(reaction, messageID)` — react via HTTP
98
+ - `api.setMessageReactionMqtt(reaction, messageID, threadID)` — react via MQTT
99
+ - `api.pinMessage(action, threadID, messageID?)` — pin/unpin/list pins
100
+ - `api.sendTypingIndicator(isTyping, threadID)` — typing status
101
+ - `api.markAsRead/markAsReadAll/markAsSeen/markAsDelivered` — message status
102
+ - `api.getThreadInfo/getThreadList/getThreadHistory/getThreadPictures` — thread data
103
+ - `api.getMessage(messageID)` — fetch a specific message
104
+ - `api.getUserInfo/getUserInfoV2/getUserID` — user data
105
+ - `api.getFriendsList/friend/unfriend` — friends management
106
+ - `api.searchForThread(name)` — search threads by name
107
+ - `api.createNewGroup/addUserToGroup/removeUserFromGroup/changeAdminStatus` — group admin
108
+ - `api.changeGroupImage/changeThreadColor/changeThreadEmoji` — group customization
109
+ - `api.gcname/emoji/nickname/theme` — per-thread personalization
110
+ - `api.muteThread/changeArchivedStatus/deleteThread` — thread management
111
+ - `api.createPoll` — create a poll in a thread
112
+ - `api.handleMessageRequest` — accept/decline message requests
113
+ - `api.changeBlockedStatus/changeAvatar/changeBio` — account actions
114
+ - `api.comment/share/follow` — social interactions
115
+ - `api.getTheme/getThemeInfo/setThreadTheme/setThreadThemeMqtt` — Messenger themes
116
+ - `api.createAITheme(prompt)` — generate AI-powered chat themes
117
+ - `api.stickers.search/listPacks/getStorePacks/addPack/getStickersInPack/getAiStickers` — sticker API
118
+ - `api.e2ee.enable/disable/getPublicKey/setPeerKey/encrypt/decrypt` — application-layer E2EE (X25519 + HKDF + AES-256-GCM)
119
+ - `api.getHealthStatus()` — MQTT, token refresh, and rate limiter telemetry
120
+ - `api.httpGet/httpPost/httpPostFormData` — raw HTTP helpers
121
+ - `api.addExternalModule(moduleObj)` — extend the API at runtime
122
+ - `api.shareContact/resolvePhotoUrl/getAccess/logout/getAppState/getCurrentUserID`
123
+ - `api.notes/gcrule/gcmember/story/realtime/getBotInfo/getBotInitialData/getUserInfoV2` — extended APIs
124
+
125
+ **TypeScript Support**
126
+ - Full `index.d.ts` with all methods, events, options, and types exported under `declare module "nkx-fca"`
127
+
128
+ **Production Monitoring**
129
+ - `ProductionMonitor` — request counts, error rates, response times, rate limit telemetry
130
+ - `api.getHealthStatus()` providing MQTT, token refresh, and rate limiter stats
131
+
132
+ ### Fixed
133
+ - Sec-Ch-Ua MQTT header aligned with Chrome 136 User-Agent (was Chrome 131)
134
+ - `sendMessageMqtt` now calls `prepareBeforeMessage` before every send
135
+ - `sendMessage` now calls `prepareBeforeMessage` before every send
136
+ - Volume limit checks (`isDailyLimitReached`, `isHourlyLimitReached`) now apply to both send paths
137
+ - TypeScript: removed duplicate `API` interface declaration and stray closing brace
138
+ - Database path renamed from `fca_kex_database` to `nkx_fca_database`
139
+ - Credits function updated to reference `nkx-fca` and `github.com/NeoKEX`
140
+
141
+ ---
142
+
143
+ > **Developed and maintained by [NeoKEX](https://github.com/NeoKEX)**
144
+ > Inspired by **ws3-fca** and **@dongdev/fca-unofficial**
@@ -0,0 +1,208 @@
1
+ # Login with Cookie Array
2
+
3
+ **nkx-fca** supports multiple authentication methods. This guide explains how to login using a cookie array instead of email/password credentials.
4
+
5
+ > **Credits:** Developed and maintained by [NeoKEX](https://github.com/NeoKEX)
6
+
7
+ ---
8
+
9
+ ## Quick Start
10
+
11
+ ```javascript
12
+ const { login } = require('nkx-fca');
13
+
14
+ const cookieArray = [
15
+ { name: 'c_user', value: 'YOUR_USER_ID' },
16
+ { name: 'xs', value: 'YOUR_SESSION_TOKEN' },
17
+ { name: 'fr', value: 'YOUR_FR_TOKEN' },
18
+ { name: 'datr', value: 'YOUR_DEVICE_TOKEN' }
19
+ ];
20
+
21
+ login({ appState: cookieArray }, {}, (err, api) => {
22
+ if (err) return console.error('Login failed:', err);
23
+ console.log('Logged in as:', api.getCurrentUserID());
24
+ });
25
+ ```
26
+
27
+ ---
28
+
29
+ ## Supported Cookie Formats
30
+
31
+ ### 1. Cookie Array with `name` property (Recommended)
32
+ ```javascript
33
+ const appState = [
34
+ { name: 'c_user', value: '123456789' },
35
+ { name: 'xs', value: 'abc123...' },
36
+ // ... more cookies
37
+ ];
38
+
39
+ login({ appState });
40
+ ```
41
+
42
+ ### 2. Cookie Array with `key` property
43
+ ```javascript
44
+ const appState = [
45
+ { key: 'c_user', value: '123456789' },
46
+ { key: 'xs', value: 'abc123...' },
47
+ ];
48
+
49
+ login({ appState });
50
+ ```
51
+
52
+ ### 3. Cookie String
53
+ ```javascript
54
+ const cookieString = 'c_user=123456789; xs=abc123...; fr=xyz...; datr=...';
55
+
56
+ login({ appState: cookieString });
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Essential Cookies
62
+
63
+ | Cookie | Purpose | Notes |
64
+ |--------|---------|-------|
65
+ | `c_user` | User ID | Your Facebook user ID |
66
+ | `xs` | Session Token | Authentication token, required |
67
+ | `fr` | Fraud Detection | Device/browser fingerprint |
68
+ | `datr` | Device Token | Device identifier |
69
+
70
+ ---
71
+
72
+ ## How to Extract Cookies from Browser
73
+
74
+ ### Chrome / Firefox / Edge
75
+ 1. Navigate to `facebook.com` and log in normally
76
+ 2. Open Developer Tools — press **F12**
77
+ 3. Go to **Application** → **Cookies** → **facebook.com**
78
+ 4. Find and copy these cookies: `c_user`, `xs`, `fr`, `datr`
79
+
80
+ ### Export as Array (from browser console)
81
+ ```javascript
82
+ copy(JSON.stringify(
83
+ document.cookie.split('; ').map(c => {
84
+ const [name, ...rest] = c.split('=');
85
+ return { name, value: rest.join('=') };
86
+ })
87
+ ))
88
+ ```
89
+
90
+ ### Using a Browser Extension
91
+ - **Chrome/Edge:** "C3C FbState" or "CookieEditor"
92
+ - **Firefox:** "Cookie-Editor"
93
+
94
+ Export the cookies as JSON and save as `appstate.json`.
95
+
96
+ ---
97
+
98
+ ## Complete Example
99
+
100
+ ```javascript
101
+ const fs = require('fs');
102
+ const { login } = require('nkx-fca');
103
+
104
+ const appState = JSON.parse(fs.readFileSync('appstate.json', 'utf8'));
105
+
106
+ login({ appState }, {
107
+ online: true,
108
+ listenEvents: true,
109
+ autoMarkRead: true,
110
+ autoReconnect: true,
111
+ simulateTyping: true
112
+ }, (err, api) => {
113
+ if (err) return console.error('Login failed:', err);
114
+
115
+ console.log('Logged in as:', api.getCurrentUserID());
116
+
117
+ api.listenMqtt((err, event) => {
118
+ if (err || event.type !== 'message') return;
119
+ console.log(`[${event.threadID}] ${event.senderID}: ${event.body}`);
120
+ });
121
+ });
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Cookie Refresh
127
+
128
+ Facebook cookies may expire after hours or days. If login fails:
129
+ 1. Log in to Facebook in your browser
130
+ 2. Export fresh cookies using a browser extension
131
+ 3. Replace your `appstate.json` with the new cookies
132
+ 4. Restart your bot
133
+
134
+ ---
135
+
136
+ ## Security Notes
137
+
138
+ - **Never commit `appstate.json` to version control**
139
+ - **Never share your cookies publicly**
140
+ - Store cookies in environment variables or secure files (`.env`, secrets manager)
141
+ - Rotate cookies periodically for long-running bots
142
+ - Each cookie set is tied to a specific browser/device session — do not reuse across machines
143
+
144
+ ---
145
+
146
+ ## Troubleshooting
147
+
148
+ ### Login Fails with Cookie Array
149
+ - Ensure `c_user` and `xs` cookies are present
150
+ - Check if the cookies are expired — extract fresh ones from your browser
151
+ - Verify cookie format: array of objects with `name` and `value` (or `key` and `value`)
152
+ - Make sure you are using cookies from a logged-in Facebook session
153
+
154
+ ### Cookies Expire Quickly
155
+ - Facebook cookies expire faster when used from a new IP or User-Agent
156
+ - Use a consistent residential proxy to extend cookie life
157
+ - Avoid switching network locations frequently
158
+
159
+ ### Account Suspended / Checkpoint
160
+ - Stop all bot activity immediately
161
+ - Complete any Facebook security check in your browser
162
+ - Wait at least 24–48 hours before resuming
163
+ - Reduce message frequency and enable warmup mode on restart
164
+
165
+ ---
166
+
167
+ ## Alternative: Email/Password Login
168
+
169
+ > Email/password login is not recommended for bots — it triggers stricter security checks.
170
+
171
+ ```javascript
172
+ login({
173
+ email: 'your-email@example.com',
174
+ password: 'your-password'
175
+ }, {}, (err, api) => {
176
+ if (err) return console.error(err);
177
+ console.log('Logged in:', api.getCurrentUserID());
178
+ });
179
+ ```
180
+
181
+ ---
182
+
183
+ ## AppState Backup
184
+
185
+ **nkx-fca** automatically saves and restores your session state internally.
186
+ To manually save the current session after login:
187
+
188
+ ```javascript
189
+ const fs = require('fs');
190
+
191
+ login({ appState }, {}, (err, api) => {
192
+ if (err) return;
193
+ // Save refreshed appState
194
+ fs.writeFileSync('appstate.json', JSON.stringify(api.getAppState(), null, 2));
195
+ });
196
+ ```
197
+
198
+ ---
199
+
200
+ ## See Also
201
+ - [README.md](./README.md) — Full feature overview
202
+ - [examples/](./examples/) — Working code examples
203
+ - [CHANGELOG.md](./CHANGELOG.md) — Version history
204
+
205
+ ---
206
+
207
+ > **Credits:** nkx-fca is developed and maintained by [NeoKEX](https://github.com/NeoKEX).
208
+ > Inspired by **ws3-fca** and **@dongdev/fca-unofficial**
package/LICENSE ADDED
@@ -0,0 +1,3 @@
1
+ All rights reserved to NeoKEX(github.com/NeoKEX)
2
+ ❌ PLEASE DO NOT STOLE MY SOURCE CODES AND CLAIM AS YOURS
3
+ Thanks for supporting ^_^