Releases: RaheemJnr/pocket-node
v1.7.1 — launch-crash hotfix
Hotfix for a launch crash that affected users upgrading from v1.6.x to v1.7.0.
What happened
After the V1→V2 keystore migration ran on first launch of v1.7.0, the post-auth navigation path tried to decrypt the key bundle just to read a plaintext flag (mnemonicBackedUp). V2 rows require an authenticated Cipher, so the read threw V2KeyMaterialRequiresAuthException on the main thread and killed the process.
Symptom for users: auth succeeds, then the app crashes before reaching the home screen. Reported via Telegram (matt, S24 Ultra) within an hour of v1.7.0 going live.
Fix
KeyMaterialEntity.walletType and KeyMaterialEntity.mnemonicBackedUp are plaintext columns. They never needed decryption. The flag readers and the flag-only writer now go through direct Room column queries on KeyMaterialDao, so V2 rows work without a Cipher.
The sign / private-key / mnemonic read paths still correctly require a Cipher — those need the actual key material and trigger BiometricPrompt at the call site.
Six new Robolectric tests around KeyStoreMigrationHelper.{get,set}MnemonicBackedUpFlag and getWalletTypeFlag pin the V2 behavior so a future refactor that reintroduces a decryption call on the flag path breaks loudly in unit tests instead of crashing post-upgrade users.
Upgrading
In-app upgrade from v1.7.0 surfaces this within a day. Sideload installs apply immediately. Wallets on v1.6.x can either install v1.7.0 first (broken launch, but the row migrates fine) and then v1.7.1, or skip straight to v1.7.1.
Migration is idempotent. No data loss either way.
PRs
- #284 fix(wallet): flag-only read path for V2 key_material
- #285 test(migration): pin V2 flag-only read/write path
Acknowledgments
matt for catching it on the S24 Ultra and posting the full stacktrace so this could ship within two hours of v1.7.0.
v1.7.0
Pocket Node v1.7.0
The biggest user-visible release since Multi-Wallet (M3). Closes nine bug reports from Telegram users, ships the Milestone 4 security work (V2 Keystore migration on mnemonic reveal, Argon2id PIN already shipped in v1.6.x), and brings the website rebuild to pocket-node.com.
What's new
Recovery is no longer a dead-end
Forgot your PIN? Tap Forgot PIN on the unlock screen, confirm the destructive reset, and import your wallet from the recovery phrase. Previously the recovery flow navigated to the regular import screen which refused already-imported phrases — a permanent lockout for anyone who had actually forgotten their PIN. The back arrow on the same flow is also fixed; cancelling returns you to the unlock screen instead of trapping you.
Mnemonic display requires biometric
Viewing your seed phrase in Settings now triggers a BiometricPrompt (or device-credential fallback) instead of just a PIN check. Existing wallets created under v1.6.x silently upgrade to the V2 auth-bound Keystore key chain the first time you tap "View seed phrase".
Wallet management UX
- The Add button on each parent wallet card now opens the sub-account form with the parent pre-selected, instead of silently switching the active wallet.
- Deleting the active wallet auto-switches to a sibling first, instead of refusing with a dead-end message.
- Deleting the only wallet now points you at the Forgot-PIN destructive reset flow.
Onboarding consistency
- Creating your first wallet now prompts for a name, matching the AddWallet flow inside the app.
- Adding a new parent wallet from inside the app now runs the same 3-step recovery-phrase confirmation as first-wallet onboarding.
No-device-lock is a warning, not a block
If your phone has no screen lock set, wallet creation now shows a warning dialog with three options — Cancel, Open Settings, Continue anyway — instead of refusing outright. The wallet creates at the V1 key chain and upgrades automatically once you enable a device lock.
DAO APC
- Fixed the APC math for cells in the withdrawing phase. The previous calculation used wall-clock now as the upper bound, but compensation stops accruing the moment a deposit transitions to withdrawing. Realized APC on withdrawing cells will now read higher (and correctly).
- Tapping the APC label opens a tooltip explaining the difference between realized APC (what Pocket Node shows — actual on-chain compensation per actual elapsed time) and theoretical APC (what Neuron shows — forward-looking projection from CKB tokenomics).
Fresh-wallet sync lands on the real tip
SyncCoordinator now polls the light client's tip header for up to 5 seconds before registering scripts. The previous flow asked for the tip immediately after node-init and got a null while peers were still handshaking, which caused SyncMode.NEW_WALLET to fall back to the hardcoded 18.3M checkpoint — visible to the user as a sync bar that started "hundreds of thousands of blocks behind" instead of instantly synced.
Background sync no longer crashes on Samsung
Multiple users on Samsung devices reported the app crashing after long backgrounding. Three related fixes:
- Missing
SupervisorJobonGatewayRepository.scope— any uncaught throwable inside the sync-polling loop propagated up to the Thread default handler and crashed the process. SyncForegroundService.onStartCommandnow catchesForegroundServiceStartNotAllowedExceptionand similar OEM exceptions; notification update path catchesSecurityExceptionon revokedPOST_NOTIFICATIONS.- Android 14+ FGS time-limit (
Service.onTimeout) now stops the service cleanly before the system kills the process withForegroundServiceDidNotStopInTimeException.dataSyncis capped at ~6h per 24h window; the previous code ignored the callback and crashed on the main thread.
Wording: "We keep an encrypted copy..." → "An encrypted copy is stored on this device"
The PIN setup screen previously read like the publisher held a copy of the recovery phrase. The phrase is stored only on the device under PIN-encrypted backup. Wording fixed to match.
Under the hood
- CI smoke harness rewritten to poll PIN-screen titles instead of counting dispatched taps. Stops admin-merge from being the default path for unrelated PRs.
- Website rebuilt from a single-file static HTML to Next.js 15 + Tailwind 3 on
pocket-node.com, with the user guide rendered natively at/guide. - Embedded WebView for the explorer block-height lookup (in-process containment, host whitelist, BiometricPrompt-free).
- Direct APK download from the website's Download button (resolves the latest release at request time; no more landing on the GitHub releases page).
- Phase 1 security audits (#186 JNI, #187 Keystore, #188 Deps) and the Codex security scan umbrella (#184) closed with PR-map summaries.
Installation
GitHub Release (current)
Download the APK below and tap to install. Android will ask permission to install from this source the first time. Updates from here forward arrive via the in-app updater.
Google Play Store (coming soon)
Listing in preparation. v1.7.0 is also packaged as the closed-testing build.
Upgrading from v1.6.x
In-place upgrade. Migrations 8→9 and 9→10 run silently on first launch.
The V2 Keystore migration runs lazily the first time you reveal your seed phrase or send a transaction. One BiometricPrompt the first time; subsequent reveals are also one prompt.
Full PR list
Telegram bug fixes: #272 #273 #274 #275 #276 #277 #278 #279 #281 #282
Smoke harness: #270
Direct download: #269
Explorer WebView: #271
Website rebuild: #265 + #267 + #268
Listing + docs: #260 #262 #266
Audit close-outs: #184 #186 #187 #188
Acknowledgments
Telegram users Radoslav, georgiev, and matt for the bug reports that drove most of the user-facing fixes in this release. CodeRabbit + Codex reviewers for the catches.
Pocket Node v1.6.1
What's new in v1.6.1
Hotfix targeting the auto-update flow that landed in v1.6.0.
- Auto-update now actually works. A compact banner sits above the bottom navigation and shows real-time download progress. Tap when ready to install.
- If the app needs install-from-unknown-sources permission, returning from Android settings resumes the download automatically. No more re-tapping Update.
- Cancel an in-progress download by tapping the banner. Retry a failed one the same way.
- The downloaded APK is cleaned up after install or cancellation, so the update never sits around eating disk.
Under the hood
- Replaced Android's DownloadManager with Ktor streaming. DownloadManager stalled at 87-95% on emulator + several real handsets, and provided no in-app progress.
- HTTP response status is validated before writing to disk, so a 404 or HTML error page can never be mistakenly mounted as an APK.
- Failed-retry race fixed:
cancelAndJoinserializes retry attempts so a prior cancellation cannot delete a new in-flight download. HomeViewModel.onClearedno longer cancels the singleton downloader; the banner is driven fromMainScreenand survives tab switches.
Upgrade path
Tested install-over-v1.6.0 on a Pixel 7 Pro emulator: wallet, PIN, balance, and sync state preserved through the Room schema migration.
Install
The in-app updater on v1.6.0 will pick this up automatically. If you are on v1.5.0 / v1.5.1, sideload manually once from the asset below; from v1.5.2 onward auto-update works.
Pocket Node v1.6.0
What's new in v1.6.0
- External links (block explorer, GitHub) now open in an in-app browser tab. Returning to the wallet keeps you in the same task, so your phone's lock or face unlock does not re-engage on the way back.
- Fixes a bug where your sync mode choice on first wallet registration could be silently overwritten back to the default.
- First-run sync overlay now appears above the sync card with the Got-it button always reachable, and you can dismiss it by tapping outside or pressing back.
- Peers connected indicator on Home is now tappable and opens Node Status directly, no more navigating through Settings.
- Removed the repeating "Protect your funds" pop-up. The home banner still surfaces backup and PIN setup.
Upgrade path
Verified install-over-v1.5.2 on a Pixel 7 Pro emulator: wallet, PIN, balance, and sync state all preserved through the Room schema migration.
Under the hood
Not surfaced in the in-app changelog but worth knowing if you debug:
- Auto-update URL now lives in BuildConfig with a unit test guarding its shape so the v1.5.0 / v1.5.1 stale-fork-URL regression cannot ship again (#142B).
- Walking-migration test replaces the in-memory builder pattern, exercising every migration from v1 to current (#147).
- Upgrade-smoke harness runs install-over-prev-main on every PR (#152 through #167).
- Debug builds now show a DEBUG pill with the short git SHA next to the version row so testers can report exactly which commit their build is from (#172).
Install
Sideload PocketNode-v1.6.0.apk. The in-app updater on v1.5.2 will pick this up automatically.
Pocket Node v1.5.2 — Hotfix Release
Hotfix release
Fixes two regressions in v1.5.1 that prevented users from upgrading.
What's fixed
- Crash on launch when upgrading from v1.5.0 (or earlier). Room's schema validation rejected the database because the v1.5.1 entity declarations did not match the migrated schema. Fixed by aligning the entity annotations and adding
MIGRATION_8_9that converges the two divergent v8 schemas (upgrade-from-v1.5.0 vs fresh-install-on-v1.5.1) into a single canonical shape. - In-app update notification was silently broken.
UpdateRepositorypolled a stale fork URL that returned 404, so the "new version available" dialog never fired in v1.5.0 or v1.5.1. Fixed to point at the actual project repo.
Important note for v1.5.0 / v1.5.1 users
The auto-update fix is in v1.5.2. Users running v1.5.0 or v1.5.1 will not receive an automatic update notification because the URL was wrong in both. You need to install v1.5.2 manually from this release page or from the website. From v1.5.2 onward, auto-update works.
Download
PocketNode-v1.5.2.apk attached to this release.
Requirements
- Android 8.0 (API 26) and up.
- ARM64 / ARMv7 only.
Pocket Node v1.5.1 — User Education Release
User Education Release
This release ships the user-education work tracked in #90, plus the strings infrastructure groundwork in #133. Aimed at making first-time users — especially those without a crypto background — understand what their phone is doing during sync, why it matters, and how to navigate the sync mode picker without prior knowledge.
What's new
- First-run sync coachmark — On the first sync, a one-time spotlight on the home Sync card explains: "Setting up — about 2 minutes. Your phone is checking the blockchain itself, no middleman server." Dismissed with Got it and never shown again.
?help icons with plain-language bottom sheets:- On the Sync and Activity sections of Home.
- On every option in the sync mode picker.
- On the Block Height field when From a specific date is selected.
- FAQ screen at Settings → Help & FAQ — 10 entries covering sync, sync modes, block height, Pending status, confirmations, balance delay, and more. Help icons deep-link to the relevant entry.
- Sync mode picker rewritten — replaced the old AlertDialog with a ModalBottomSheet. Each option now carries a "Pick this if…" sentence:
- New wallet → Pick this if you have never received CKB before.
- Recent activity (Recommended) → Pick this if you used a CKB wallet in the last month.
- From a specific date → Pick this if you know roughly when your first CKB transaction was.
- All history → Pick this only if you need every transaction since CKB launched.
- Block height removed from Home — the sync card and top-bar chip now show plain language only. Block height remains visible on Node Status for power users.
- Catching-up text now shows progress — "Catching up from 18,250,000 to 18,310,422" with the values formatted with thousands separators.
- Help & FAQ in Settings — discoverable entry point for the new FAQ screen.
Reliability fixes
- Sync sheet survives the explorer round-trip — Tapping "Don't know your block height? Look up on explorer" opens Chrome. On aggressive memory managers (Tecno/Infinix etc.) the app process is killed; previously the user landed back on Home with the sheet gone after PIN unlock. Both the settings-path and post-import sync sheets are now persisted across process death.
- Node Status no longer freezes after a sync mode change — a JNI exception during the brief restart window used to leave the displayed block number stuck on the previous mode's value. Each query is now individually fault-tolerant.
- Coachmark grace timer no longer races with sync mode change —
stopSyncPolling()now resets the first-catching-up timestamp, and an in-flight polling response that returns just before stop can no longer resurrect it (generation-token gate). - Coachmark spotlight has rounded corners matching the sync card; tap-swallow scrim prevents accidental taps on backgrounded UI.
WalletPreferences.clear()re-syncs StateFlows so observers don't read stale values until process restart.- Coachmark anchor cleanup — bounds entries are removed on dispose, no stale coordinates left behind.
Accessibility
- FAQ back arrow now announces "Back" to TalkBack instead of being unlabeled.
- Help icons across the sync sheet have proper content descriptions.
Localization groundwork
- Migrated 4 small components and the entire sync mode picker to
strings.xml. New copy added in this release is fully resource-backed. - Forward-compatible with
values-xx/directories. No translations shipped in this release; tracked in #132.
Out of scope (deferred)
- Mnemonic flow refresh / "Recovery Phrase" terminology rename — separate brainstorm.
- "What if I lose my phone?" setup-time story — pending the encrypted-cloud-backup decision.
- Translations themselves — tracked in #132.
- Migration of remaining hardcoded strings on screens not touched by #90 — tracked in #133.
Upgrade notes
- Existing users will see the coachmark on their next active sync if they haven't seen it before.
- No data migration. The
hasSeenSyncCoachmarkflag is per-install, so reinstalling the app re-arms the coachmark.
Requirements
- Android 8.0 (API 26) and up.
- ARM64 / ARMv7 only.
Pocket Node v1.5.0
M3: Multi-Wallet & Key Storage Redesign
Highlights
- Multiple wallets — create, import, and switch between separate mnemonic and raw-key wallets.
- HD sub-accounts — derived from a parent mnemonic with their own addresses and balances.
- Mandatory PIN — required while a wallet exists. Protects the on-device encrypted recovery-phrase backup. Existing users are prompted once after upgrading.
- Key storage redesign — private keys moved from EncryptedSharedPreferences to Room, encrypted with an Android Keystore AES-256-GCM key. ESP fallback retained for one release.
- Per-wallet sync — transactions, balance cache, DAO cells, and sync mode all scoped per wallet.
- CSV transaction export — with UTF-8 BOM for correct Excel rendering.
- Infinite-scroll transaction list (Paging 3).
Multi-wallet guards
- Can't delete the active wallet — must switch first.
- Can't delete a parent wallet that has sub-accounts.
- Can't import the same mnemonic or raw key twice under different names.
- Can't rename a wallet to a name that another wallet already uses.
- Can't remove the PIN while any wallet exists.
Stability & correctness
- Startup migration failure now surfaces as a node-ready error instead of suspending forever.
- Wallet deletion uses a Room transaction; key material is destroyed only after the DB row commits.
- Sync progress tracker resets on wallet switch so the new wallet starts with a clean baseline.
sendTransactionpost-send rescan captures the sender wallet up front, so switching wallets during the 5s delay no longer re-registers the wrong script.- Session PIN is wired into KeyManager via AuthManager — PIN-encrypted backups are now actually written on every key update.
- Session PIN is cleared on app backgrounding.
Upgrade notes
- Upgrading from 1.x to 1.5.0 prompts for PIN setup on first launch. No action is needed beyond setting the PIN — existing wallet keys migrate automatically.
- Sub-accounts require a mnemonic parent wallet.
- Newly created wallets default to NEW_WALLET sync mode (start from current tip, no history walk).
Requirements
- Android 8.0 (API 26) and up.
- ARM64 / ARMv7 only. x86 emulator builds are not included.
Pocket Node v1.4.1 — Bugfix Release
What's Fixed
-
Onboarding bypass — Closing the app during mnemonic backup verification no longer skips you to the dashboard. The app remembers where you left off and sends you back to complete verification.
-
"Mnemonic not found" after upgrade — Fixed a race condition in wallet data persistence and added a crash guard for encryption key mismatches during APK upgrades. Wallet data is now written atomically.
-
Network switch now visibly restarts — Switching between Mainnet and Testnet now properly closes and immediately reopens the app instead of silently killing the process.
-
In-app dark mode toggle — No longer need to change system settings. Go to Settings > Appearance > Theme and choose System, Light, or Dark.
-
Import via mnemonic no longer gates backup — Users importing via seed phrase already know their words, so they go straight to the dashboard.
-
Removed redundant settings icon — The gear icon in the home top bar has been removed since Settings is in the bottom nav.
Version
versionName: 1.4.1versionCode: 5- Min SDK: 26 (Android 8.0)
Install
Download the APK below and install on your Android device. You may need to enable "Install from unknown sources" in your device settings.
v1.4.0 — Nervos DAO Protocol Integration
What's New
Nervos DAO Integration
- Deposit to DAO: Lock CKB in the Nervos DAO to earn compensation (minimum 102 CKB)
- Withdraw from DAO (Phase 1): Initiate withdrawal, converting deposit cell to withdrawing cell
- Unlock from DAO (Phase 2): Claim deposited CKB + accumulated compensation after 180-epoch lock period
- Compensation tracking: Real-time display of accrued DAO compensation per deposit
- Cycle progress: Visual progress bar showing position within current 180-epoch lock cycle with phase indicators (Normal → Suggested → Ending)
- Lock countdown: Hours remaining until unlock displayed for locked deposits
- 7-state DAO FSM: Full deposit lifecycle tracking (Depositing → Deposited → Withdrawing → Locked → Unlockable → Unlocking → Completed)
- Auth-gated deposits: Biometric or PIN authentication required before DAO deposits
JNI DAO Utilities (Rust)
nativeExtractDaoFields: Parse DAO header into C/AR/S/U fieldsnativeCalculateMaxWithdraw: Compute deposit + compensation using RFC-0023 formulanativeCalculateUnlockEpoch: Calculate phase 2 unlock epoch with 180-epoch boundary rounding
UI
- New DAO tab with deposit list, deposit bottom sheet, and compensation progress bars
- DAO transaction badges in activity feed (DAO Deposit, DAO Withdraw, DAO Unlock)
- Neuron-style deposit cards with status, compensation, and lock info
- Learn CKB link added to website navbar and footer
Testing
- 9 new test files covering DAO models, constants, direction detection, transaction building, ViewModel state, and formatting
Bug Fixes & Hardening
- Paginated cell/transaction fetching for large deposit sets
- Epoch fraction validation (length > 0, index < length)
- Max withdraw return value guards preventing silent corruption
- Deposit block hash preservation on header fetch failure
- Clipboard auto-clear after 30s when copying private key
v1.3.0 — Nervos DAO Protocol Integration
What's New
Nervos DAO Integration (Milestone 2)
- Deposit to DAO: Lock CKB in the Nervos DAO to earn compensation (minimum 102 CKB)
- Withdraw from DAO (Phase 1): Initiate withdrawal, converting deposit cell to withdrawing cell
- Unlock from DAO (Phase 2): Claim deposited CKB + accumulated compensation after 180-epoch lock period
- Compensation tracking: Real-time display of accrued DAO compensation per deposit
- Cycle progress: Visual progress bar showing position within current 180-epoch lock cycle with phase indicators (Normal → Suggested → Ending)
- Lock countdown: Hours remaining until unlock displayed for locked deposits
- 7-state DAO FSM: Full deposit lifecycle tracking (Depositing → Deposited → Withdrawing → Locked → Unlockable → Unlocking → Completed)
- Auth-gated deposits: Biometric or PIN authentication required before DAO deposits
JNI DAO Utilities (Rust)
nativeExtractDaoFields: Parse DAO header into C/AR/S/U fieldsnativeCalculateMaxWithdraw: Compute deposit + compensation using RFC-0023 formulanativeCalculateUnlockEpoch: Calculate phase 2 unlock epoch with 180-epoch boundary rounding
UI
- New DAO tab with deposit list, deposit bottom sheet, and compensation progress bars
- DAO transaction badges in activity feed (DAO Deposit, DAO Withdraw, DAO Unlock)
- Neuron-style deposit cards with status, compensation, and lock info
- Learn CKB link added to website navbar and footer
Testing
- 9 new test files covering DAO models, constants, direction detection, transaction building, ViewModel state, and formatting
Bug Fixes & Hardening
- Paginated cell/transaction fetching for large deposit sets
- Epoch fraction validation (length > 0, index < length)
- Max withdraw return value guards preventing silent corruption
- Deposit block hash preservation on header fetch failure
- Clipboard auto-clear after 30s when copying private key